How to add a number of points on a current view of plotly scatterplot?

Viewed 19

I have a plotly generated plot in python. It can be zoomed or a specific region selected by window selection.

Is there any solution to calculate current number of points on current view of scatterplot?

E.g. initial screen gives us 1000 points, but when I zoom or using a window to choose any specific area - I want to see that this area includes only 100 points from initial scatterplot. Is it possible? Or maybe to get bounds from x-axis of a plot to use it in further dashboard - e.g. to calculate max/min/mean values for the points on the screen..

1 Answers
  • you clearly state dashboard hence assuming dash
  • zoom and pan result in relayoutDatacallback being triggered
  • this passes a dict which can be parsed for min/max x and y
  • code below shows this, filtering dataframe used to create scatter to get number of points
import dash
import plotly.express as px
from dash.dependencies import Input, Output, State
from jupyter_dash import JupyterDash
import numpy as np
import pandas as pd

r = np.random.RandomState(42)

# some data to plot
df = pd.DataFrame(
    {"x-val": np.linspace(1, 100, 1000), "y-val": r.uniform(1, 100, 1000)}
)

fig = px.scatter(df, x="x-val", y="y-val")


app = JupyterDash(__name__)
app.layout = dash.html.Div(
    [dash.dcc.Graph(id="graph", figure=fig), dash.html.Div(id="debug")]
)


# simple callback capture zoom and pan
@app.callback(Output("debug", "children"), Input("graph", "relayoutData"))
def figEvent(relayoutData):
    r = relayoutData
    # parse out min & max values displayed
    rng = {
        ax: [df[c].min(), df[c].max()]
        if f"{ax}axis.range[0]" not in r.keys()
        else [r[f"{ax}axis.range[0]"], r[f"{ax}axis.range[1]"]]
        for ax, c in zip("xy", ["x-val", "y-val"])
    }
    # filter dataframe and get number of rows
    n = df.loc[df["x-val"].between(*rng["x"]) & df["y-val"].between(*rng["y"])].shape[0]

    return n


app.run_server(mode="inline", debug=True)
Related