You can create a JupyterDash
app, and use a callback to read in the layout data from zoom events, then update the figure accordingly. In order to reset the default (with all of the points and traces in the legend), you can click Zoom Out
tooltip in the figure.
import json
import numpy as np
import pandas as pd
import plotly.express as px
from jupyter_dash import JupyterDash
from dash import dcc, html, Input, Output
# Sample Data
np.random.seed(42)
proj_2D = pd.DataFrame({
'x': np.random.uniform(low=0.0, high=1.0, size=100),
'y': np.random.uniform(low=0.0, high=1.0, size=100),
'topic': list(range(1,11))*10
})
proj_2D['topic'] = proj_2D['topic'].astype(str)
fig_2d = px.scatter(
proj_2D, x='x', y='y',
color='topic'
)
fig_2d.update_traces(marker=dict(size=5),
selector=dict(mode='markers'))
fig_2d.update_layout(
autosize=False,
width=1000,
height=800,
)
# Build App
app = JupyterDash(__name__, prevent_initial_callbacks=True)
app.layout = html.Div([
html.H1("JupyterDash Scatter Zoom Update"),
dcc.Graph(id='scatter-fig', figure=fig_2d),
])
@app.callback(
Output('scatter-fig', 'figure'),
Input('scatter-fig', 'relayoutData'),
)
def display_relayout_data(relayoutData):
xaxis_min, xaxis_max = relayoutData["xaxis.range[0]"], relayoutData["xaxis.range[1]"]
yaxis_min, yaxis_max = relayoutData["yaxis.range[0]"], relayoutData["yaxis.range[1]"]
## subset data
proj_2D_new = proj_2D[
proj_2D['x'].between(xaxis_min, xaxis_max) &
proj_2D['y'].between(yaxis_min, yaxis_max)
]
fig_2d = px.scatter(
proj_2D_new, x='x', y='y',
color='topic'
)
fig_2d.update_traces(marker=dict(size=5),
selector=dict(mode='markers'))
fig_2d.update_layout(
autosize=False,
width=1000,
height=800,
)
return fig_2d
# Run app and display result inline in the notebook
app.run_server(mode='inline', debug=True, port=8000)
