bqplot
bqplot copied to clipboard
Lines mark does not respect min and max of LinearScale
Describe the bug Updates to the y values of a Lines mark (fill inside 2 lines) changes the min and max of x and y scales. No matter how I specify the max y-value of the scale, the Lines mark ignores that limit and is allowed to extend beyond the fixed heatmap.
To Reproduce
from bqplot import HeatMap, Lines, Figure, LinearScale, Axis
from ipywidgets import IntSlider
import numpy as np
from IPython.display import display
# create random data
data = np.random.random(( 278 , 278 ))
domain = np.arange(278)
# create scales and axes
x_sc = LinearScale(min=0, max=278, allow_padding=False)
y_sc = LinearScale(min=0, max=278, allow_padding=False)
ax_x = Axis(label='Time', scale=x_sc)
ax_y = Axis(label='Time', scale=y_sc, orientation='vertical')
# create marks and slider widget
hm = HeatMap(color=data, x=domain, y=domain, scales={'x': x_sc, 'y': y_sc, 'color': ColorScale(scheme="Greys")})
line = Lines(x=domain, y=[domain, domain], scales={'x': x_sc, 'y': y_sc}, fill_colors='red', fill="inside", fill_opacities=[0.3, 0.3], stroke_width=0, apply_clip=True, preserve_domain={'x': True, 'y':True})
figure = Figure(marks=[hm, line], axes=[ax_x, ax_y], title='RP', layout=Layout(width="500px", height="500px", overflow="visible", padding_y=0, padding_x=0, min_aspect_ratio=1, max_aspect_ratio=1))
theiler = IntSlider(value=1, min=1, max=20, step=1, description="Theiler Window", continuous_update=False)
# fill between 2 lines fix
def transform_to_area(x_data, y1, y2):
return np.append(x_data, x_data[::-1]), np.append(y1, y2[::-1])
# slider callback
def update_line(change):
with line.hold_sync():
y1, y2 = domain+theiler.value, domain-theiler.value
x_area, y_area = transform_to_area(domain, y1, y2)
line.x = x_area
line.y = y_area
# try to reset axes range
plt.ylim(0, 278)
x_sc.min, y_sc.min = 0, 0
x_sc.max, y_sc.max = 278, 278
# show slider and figure
theiler.observe(update_line)
display(theiler, figure)
Expected behavior As the slider changes, the Lines mark should become thicker (as the slider value corresponds to the number of diagonals to include in the red window) but not change the original axis range (i.e. of the heatmap). The Lines mark should stay within the Figure bounds of [0, 278] at all times.
Screenshots
Additional context
Setting apply_clip=True
and preserve_domain: {'x': True, 'y': True}
to the Mark also doesn't limit the Lines mark to the domain specified when creating the scales. Have tried the suggested fix from #880 (i.e. plt.ylim()
) and updating the min and max attributes of the scales both inside and outside of the line.hold_sync()
block. Makes no difference -- the Lines mark still ignores the specified domain.
Also, the fill between 2 lines fix is the workaround suggested in #523. I've also tried creating the fill by using fill="between"
with y1
and y2
but that only works when initially plotted and no Lines mark appears when the slider is changed. Don't know if how the Lines mark is created affects this behavior at all.
Apologies in advance if I messed up anything, this is my first time contributing/reporting an issue on Github.