Replies: 4 comments 7 replies
-
First of all, the I have created the After making this change the code looks like from typing import List
import reflex as rx
import plotly.graph_objects as go
import numpy as np
np.random.seed(1)
class MapState(rx.State):
fig: go.Figure = go.Figure()
colors: List[str] = ['#a3a7e4'] * 100
size: List[int] = [10] * 100
def load_map(self):
x = np.random.rand(100)
y = np.random.rand(100)
self.fig = go.Figure([go.Scatter(x=x, y=y, mode='markers')])
scatter = self.fig.data[0]
scatter.marker.color = self.colors
scatter.marker.size = self.size
self.fig.layout.hovermode = 'closest'
def map():
return rx.vstack(
rx.text("Map"),
rx.plotly(data=MapState.fig, height="400px"),
# Here you can see what the browser gets to render the figure using react-plotly
rx.text(MapState.fig.to_string()),
)
app = rx.App()
app.add_page(map, route="/map", on_load=MapState.load_map) Note how the page has This is required because the state vars, like |
Beta Was this translation helpful? Give feedback.
-
The second issue is that In order to handle click events generated in the browser, we need to attach an Until Reflex exposes these event triggers however, we can subclass from typing import Any, Dict, List
import reflex as rx
from reflex.components.plotly.plotly import Plotly
class PlotlyTriggers(Plotly):
"""Display a plotly graph with triggers."""
def get_event_triggers(self) -> Dict[str, Any]:
return {
**super().get_event_triggers(),
"on_click": lambda e0: [e0],
}
plotly = PlotlyTriggers.create This will allow the Add a def _get_custom_code(self) -> str | None:
return """
const extractPoints = (points) => {
return points.map(point => {
return {
x: point.x,
y: point.y,
curveNumber: point.curveNumber,
pointNumber: point.pointNumber,
pointIndex: point.pointIndex,
'marker.color': point['marker.color'],
'marker.size': point['marker.size'],
bbox: {
x0: point.bbox.x0,
x1: point.bbox.x1,
y0: point.bbox.y0,
y1: point.bbox.y1,
}
}
})
}
""" When using Finally we need to replace the generic event arg definition ( class _ClickEvent(rx.Base):
event: Any
points: List[Dict] The following signature function is used to provide a mapping from the javascript args ( def _on_click_signature(e0: _ClickEvent) -> List[Any]:
return [
e0.event,
rx.Var.create_safe(
f"extractPoints({e0.points})",
),
] Now update the def get_event_triggers(self) -> Dict[str, Any]:
return {
**super().get_event_triggers(),
"on_click": _on_click_signature,
} |
Beta Was this translation helpful? Give feedback.
-
With our new def update_point(self, event, points):
# Get a reference to the scatter plot in the figure.
scatter = self.fig.data[0]
# Get mutable color and size lists for each point.
c = list(scatter.marker.color)
s = list(scatter.marker.size)
# Update the point values.
for point in points:
print(f"Updating point {point['pointIndex']}")
c[point["pointIndex"]] = '#bae2be'
s[point["pointIndex"]] = 20
# Assign the updated lists back to the plot.
scatter.marker.color = c
scatter.marker.size = s
# Reassign the figure to the state trigger a frontend update.
self.fig = self.fig The original code used The last line Now, the from . import plotly_triggers
...
def map():
return rx.vstack(
rx.text("Map"),
plotly_triggers.plotly(data=MapState.fig, height="400px", on_click=MapState.update_point),
# Here you can see what the browser gets to render the figure using react-plotly
rx.text(MapState.fig.to_string()),
)
... |
Beta Was this translation helpful? Give feedback.
-
Complete Codemkdir plotly-trigger-example
cd plotly-trigger-example
python3.11 -m venv VENV
. ./VENV/bin/activate
pip install reflex==0.4.4
reflex init --template blank
|
Beta Was this translation helpful? Give feedback.
-
Update 2024/10/17: Click events are supported out of the box as of reflex 0.5.3
The following hack is no longer necessary, see https://reflex.dev/docs/library/graphing/other-charts/plotly/#api-reference
On discord user
sgaseretto
asks:Beta Was this translation helpful? Give feedback.
All reactions