Search code examples
jupyter-notebookjupyterbqplot

Dynamically adjust axes in bqplot


I'm working on a jupyter based dashboard for data analysis and am planning on using bqplot for plotting the data. Part of the spec for the dashboard is to be able to adjust the axes to be able to zoom in/out on the data. So far I've been able to get this to update dynamically without needing to reload the figure entirely. Is there a way to to do this? If so, how? Below is a snippet of roughly what I mean:

def updateXAxis(values):
    #Update X-axis min/max value here

x_sc = LinearScale(min=float(x_data[0]))
y_sc = LinearScale()

ax_x = Axis(label='X', scale=x_sc, grid_lines='solid', tick_format='0f')
ax_y = Axis(label='Y', scale=y_sc, orientation='vertical', tick_format='0.2f')

m_fig = dict(left=100, top=50, bottom=50, right=100)
fig = Figure(axes=[ax_x, ax_y], marks=data_values, fig_margin=m_fig)

x_range = IntRangeSlider(value=[0,1000],
                        min=0,
                        max=2000,
                        step=1,
                        description="X Axis",
                        disabled=False,
                        continuous_update=False,
                        orientation='horizontal',
                        readout=True)
interactive(updateXAxis, values=x_range)
fig

Solution

  • The issue here ended up being that the interactive function is not very flexible. Instead observe should be used, below is an example:

    def updateXAxis(values):
        if change['type'] == 'change' and change['name'] == 'value':
            x_sc.min = change['new'][0]
            x_sc.max = change['new'][1]
    
    x_sc = LinearScale(min=float(x_data[0]))
    y_sc = LinearScale()
    
    ax_x = Axis(label='X', scale=x_sc, grid_lines='solid', tick_format='0f')
    ax_y = Axis(label='Y', scale=y_sc, orientation='vertical', tick_format='0.2f')
    
    m_fig = dict(left=100, top=50, bottom=50, right=100)
    fig = Figure(axes=[ax_x, ax_y], marks=data_values, fig_margin=m_fig)
    
    x_range = IntRangeSlider(value=[0,1000],
                            min=0,
                            max=2000,
                            step=1,
                            description="X Axis",
                            disabled=False,
                            continuous_update=False,
                            orientation='horizontal',
                            readout=True)
    
    x_range.observe(updateXAxis)
    widgets.VBox([fig, x_range])
    

    There's a slightly more detailed answer to this at the git issue I filed here: https://github.com/bloomberg/bqplot/issues/712