Die Komponentenwerkstatt: Reflex' 100 Bibliotheksbausteine
·
Kursüberblick
Layout
·
Box
·
Flex
·
Stack
·
Grid
·
Container
·
Section
·
Center
·
Spacer
·
Separator
·
Card
·
Inset
·
Aspect Ratio
·
Fragment
Typografie
·
Text
·
Heading
·
Link
·
Code
·
Markdown
·
Blockquote
·
Quote
·
Strong
·
Em
·
Kbd
Formulare
·
Button
·
Input
·
Text Area
·
Checkbox
·
Switch
·
Radio Group
·
Select
·
Slider
·
Form
·
Upload
Datenanzeige
·
Badge
·
Avatar
·
Icon
·
Callout
·
List
·
Data List
·
Code Block
·
Progress
·
Spinner
·
Scroll Area
·
Moment
Auf- und Zuklappen
·
Tabs
·
Accordion
·
Segmented Control
Overlays
·
Tooltip
·
Popover
·
Hover Card
·
Dialog
·
Alert Dialog
·
Drawer
·
Dropdown Menu
·
Context Menu
·
Toast
Dynamisches Rendern
·
Cond
·
Match
·
Foreach
·
Auto Scroll
Medien
·
Image
·
Audio
·
Video
Tabellen und Datengrids
·
Table
·
Data Table
·
Data Editor
Diagramme
·
Area Chart
·
Bar Chart
·
Line Chart
·
Composed Chart
·
Pie Chart
·
Radar Chart
·
Radial Bar Chart
·
Scatter Chart
·
Funnel Chart
·
Treemap
·
Sankey Chart
·
Error Bar
Diagrammbausteine
·
Axis
·
Cartesian Grid
·
Chart Tooltip
·
Legend
·
Label
·
Reference
·
Brush
Andere Diagrammbibliotheken
·
Plotly
·
Pyplot
HTML-Elemente
·
HTML
·
HTML Text
·
HTML Layout
·
HTML Forms
·
HTML Media
·
HTML Tables
·
SVG
Weitere Werkzeuge
·
Theme
·
Skeleton
·
Clipboard
·
Html Embed
·
Script
·
Memo
rx.plotlyOffizielle Doku
Werkstattauftrag
Bitte den Jahresumsatz je Produkt als interaktives Diagramm, in das man hinein- und herauszoomen kann, und bei Auswahl eines Produkts soll sich das Diagramm ändern.
Plotly ist eine Python-Bibliothek für interaktive Diagramme, die sich zoomen, verschieben und mit der Maus erkunden lassen. rx.plotly nimmt eine Plotly-Figure unverändert entgegen und zeichnet sie im Browser. Neben einfachen Diagrammen wie Linien und Balken nutzt du so auch Heatmaps, 3D- und Finanzdiagramme, ganz ohne JavaScript.
Statt wie in einem gewöhnlichen Skript fig.show() aufzurufen, übergibst du die Figure im UI-Code mit rx.plotly(data=fig). Das nötige Paket ist plotly; in diesem Kurs werden die Figures mit plotly.graph_objects (go) erstellt.
import plotly.graph_objects as go
plotly_years = [1952, 1957, 1962, 1967, 1972, 1977, 1982, 1987, 1992, 1997, 2002, 2007]
plotly_canada = [68.75, 69.96, 71.3, 72.13, 72.88, 74.21, 75.76, 76.86, 77.95, 78.61, 79.77, 80.65]
plotly_line_fig = go.Figure(go.Scatter(x=plotly_years, y=plotly_canada, mode="lines", name="Canada"))
plotly_line_fig.update_layout(title="Life expectancy in Canada")
rx.plotly(data=plotly_line_fig, width="100%")Die Beispiele der offiziellen Doku verwenden meist plotly.express (px). px braucht pandas, deshalb baut diese Seite dieselben Figures mit go und schreibt die Daten als Python-Listen. Auch eine mit px erstellte Figure ist eine Figure, die Übergabe an rx.plotly funktioniert also genauso.
Ein dict in layout überschreibt das Layout der Figure. Das ist praktisch, wenn du bei derselben Figure nur auf der Anzeigeseite Titel, Höhe oder Hintergrund ändern willst. Die Werkbank unten und einige Beispiele verwenden das obige plotly_line_fig weiter.
Props ausprobieren
title
height
400
showlegend
plot_bgcolor
locale
rx.plotly(
data=plotly_line_fig,
layout={"title": {"text": "Life expectancy"}, "height": 400, "showlegend": False, "plot_bgcolor": "rgba(0,0,0,0)"},
locale="en",
width="100%",
)| Prop | Werte | Standard | Verwendung |
|---|---|---|---|
data | go.Figure oder deren dict | - | Die zu zeichnende Figure. Auch ein State-Wert geht |
layout | dict | - | Werte, die das Layout der Figure überschreiben |
template | Plotly-Template | heller Modus plotly, dunkler Modus plotly_dark | Theme für alle Farben und Schriften |
config | dict | - | Plotly-Einstellungen wie Werkzeugleiste oder Scroll-Zoom |
locale | "de" "ko" … | - | Sprache für Zahlen- und Datumsformat und die Texte der Werkzeugleiste |
use_resize_handler | True / False | True | Bei geänderter Fenstergröße neu anpassen |
on_click · on_hover · on_unhover · on_selected · on_selecting | Event | - | Übergeben eine Liste von Punkten (list[dict]) |
on_relayout · on_double_click · on_deselect · on_after_plot usw. | Event | - | Zoomen und Verschieben, Doppelklick, Auswahl aufheben, nach dem Neuzeichnen (ohne Argumente) |
Ohne template wechselt Reflex das Theme passend zu hellem und dunklem Modus. rx.plotly in Reflex 0.10 hat außerdem on_click und on_double_click, die in der Tabelle der offiziellen Doku fehlen.
Das sind die Plotly-Express-Beispiele der offiziellen Doku, übertragen auf go. Welche Figure es auch ist, übergeben wird sie immer mit rx.plotly(data=figure). Die Daten sind für die Beispiele erfunden.
Mehrere go.Bar mit barmode="group" stehen nebeneinander. Das entspricht px.bar(..., color="country").
import plotly.graph_objects as go
plotly_bar_fig = go.Figure([
go.Bar(name="Chairs", x=["Q1", "Q2", "Q3", "Q4"], y=[120, 150, 170, 210]),
go.Bar(name="Tables", x=["Q1", "Q2", "Q3", "Q4"], y=[80, 95, 130, 120]),
])
plotly_bar_fig.update_layout(barmode="group", title="Orders by quarter")
rx.plotly(data=plotly_bar_fig, width="100%")Mit mode="markers" zeichnet go.Scatter nur Punkte. Legst du für jede Gruppe eine eigene trace an, bekommt jede ihre Farbe und ihren Legendeneintrag.
import random
import plotly.graph_objects as go
plotly_scatter_rng = random.Random(7)
plotly_scatter_fig = go.Figure([
go.Scatter(
x=[plotly_scatter_rng.gauss(cx, 0.3) for _ in range(30)],
y=[plotly_scatter_rng.gauss(cy, 0.4) for _ in range(30)],
mode="markers",
name=name,
)
for name, cx, cy in [("A", 3.4, 5.0), ("B", 2.8, 5.9), ("C", 3.0, 6.6)]
])
plotly_scatter_fig.update_layout(title="Sample clusters", xaxis_title="width", yaxis_title="length")
rx.plotly(data=plotly_scatter_fig, width="100%")go.Pie bekommt Namen (labels) und Werte (values). Die Anteile berechnet Plotly.
import plotly.graph_objects as go
plotly_pie_fig = go.Figure(go.Pie(labels=["Thur", "Fri", "Sat", "Sun"], values=[171.83, 51.96, 260.40, 247.39]))
plotly_pie_fig.update_layout(title="Tips by day")
rx.plotly(data=plotly_pie_fig, width="100%")go.Histogram2d färbt Felder umso dunkler, je mehr Wertepaare darin liegen (px.density_heatmap). Hast du bereits eine berechnete Tabelle, nimmst du go.Heatmap(z=...).
import random
import plotly.graph_objects as go
plotly_heat_rng = random.Random(3)
plotly_bills = [plotly_heat_rng.gauss(20, 8) for _ in range(300)]
plotly_tips = [b * 0.15 + plotly_heat_rng.gauss(0, 0.8) for b in plotly_bills]
plotly_heatmap_fig = go.Figure(go.Histogram2d(x=plotly_bills, y=plotly_tips, nbinsx=20, nbinsy=15))
plotly_heatmap_fig.update_layout(title="Bill vs tip density heatmap")
rx.plotly(data=plotly_heatmap_fig, width="100%")go.Histogram teilt die Werte in Klassen ein und zählt sie. nbinsx ist die Obergrenze für die Anzahl der Klassen.
import random
import plotly.graph_objects as go
plotly_hist_rng = random.Random(5)
plotly_hist_fig = go.Figure(go.Histogram(x=[plotly_hist_rng.gauss(20, 8) for _ in range(250)], nbinsx=20))
plotly_hist_fig.update_layout(title="Distribution of total bills")
rx.plotly(data=plotly_hist_fig, width="100%")go.Box zeigt Median, Quartile und Ausreißer in einer Box. Jede Gruppe bekommt eine eigene trace.
import random
import plotly.graph_objects as go
plotly_box_rng = random.Random(11)
plotly_box_fig = go.Figure([
go.Box(y=[plotly_box_rng.gauss(mean, 6) for _ in range(40)], name=day)
for day, mean in [("Thur", 17), ("Fri", 17), ("Sat", 20), ("Sun", 21)]
])
plotly_box_fig.update_layout(title="Total bill by day")
rx.plotly(data=plotly_box_fig, width="100%")Ein Streudiagramm, in dem die Punktgröße (marker.size) einen dritten Wert zeigt. Stellst du die x-Achse auf type="log" um, entspricht das px.scatter(..., log_x=True).
import plotly.graph_objects as go
plotly_bubble_fig = go.Figure(go.Scatter(
x=[800, 2500, 6000, 15000, 32000, 45000],
y=[52, 61, 68, 74, 79, 82],
text=["A", "B", "C", "D", "E", "F"],
mode="markers",
marker={"size": [20, 45, 30, 60, 25, 40], "color": [1, 2, 3, 4, 5, 6], "colorscale": "Viridis"},
))
plotly_bubble_fig.update_xaxes(type="log", title="income")
plotly_bubble_fig.update_layout(title="Income vs life expectancy", yaxis_title="years")
rx.plotly(data=plotly_bubble_fig, width="100%")Ein Zeitplan wird mit waagerechten Balken (orientation="h") gezeichnet. Der Anfang eines Balkens ist base, seine Länge die Dauer in Millisekunden, und die x-Achse ist eine Datumsachse. Genau das macht px.timeline intern. Die y-Achse wird umgedreht, damit man von oben nach unten liest.
from datetime import date
import plotly.graph_objects as go
plotly_jobs = [("Job A", "2009-01-01", "2009-02-28"), ("Job B", "2009-03-05", "2009-04-15"), ("Job C", "2009-02-20", "2009-05-30")]
plotly_gantt_fig = go.Figure(go.Bar(
y=[job for job, start, end in plotly_jobs],
base=[start for job, start, end in plotly_jobs],
x=[(date.fromisoformat(end) - date.fromisoformat(start)).days * 86_400_000 for job, start, end in plotly_jobs],
orientation="h",
))
plotly_gantt_fig.update_xaxes(type="date")
plotly_gantt_fig.update_yaxes(autorange="reversed")
rx.plotly(data=plotly_gantt_fig, width="100%")Hierarchische Daten werden von der Wurzel in der Mitte zu den äußeren Ringen aufgefächert. Mit labels und parents beschreibst du die Eltern-Kind-Beziehungen.
import plotly.graph_objects as go
plotly_sunburst_fig = go.Figure(go.Sunburst(
labels=["Eve", "Cain", "Seth", "Enos", "Noam", "Abel", "Awan", "Enoch", "Azura"],
parents=["", "Eve", "Eve", "Seth", "Seth", "Eve", "Eve", "Awan", "Eve"],
values=[10, 14, 12, 10, 2, 6, 6, 4, 4],
))
rx.plotly(data=plotly_sunburst_fig, width="100%")Zeigt, wie stark die Zahl von Stufe zu Stufe schrumpft, vom Besuch bis zum Kauf. Damit findest du die Stufe, an der die meisten abspringen.
import plotly.graph_objects as go
plotly_funnel_fig = go.Figure(go.Funnel(
x=[39, 27.4, 20.6, 11, 2],
y=["Website visit", "Downloads", "Potential customers", "Requested price", "Invoice sent"],
))
rx.plotly(data=plotly_funnel_fig, width="100%")locale stellt Zahlen- und Datumsformat sowie die Hinweistexte der Werkzeugleiste auf die jeweilige Sprache um. Unten ist es Deutsch. Du kannst zusätzlich config angeben; sind beide vorhanden, wird der Wert von locale zuletzt angewendet.
rx.plotly(data=plotly_line_fig, locale="de", width="100%")Gibst du go.Surface eine zweidimensionale Liste von Höhenwerten (z), entsteht eine Oberfläche. Die offizielle Doku liest Höhendaten eines Bergs aus einer CSV-Datei, hier werden per Formel erzeugte Werte verwendet. Durch Ziehen kannst du sie drehen.
import math
import plotly.graph_objects as go
plotly_surface_z = [[60 + 40 * math.sin(x / 4) * math.cos(y / 5) + y for x in range(30)] for y in range(30)]
plotly_surface_fig = go.Figure(data=[go.Surface(z=plotly_surface_z)])
plotly_surface_fig.update_traces(contours_z=dict(show=True, usecolormap=True, highlightcolor="limegreen", project_z=True))
plotly_surface_fig.update_layout(scene_camera_eye=dict(x=1.87, y=0.88, z=-0.64), margin=dict(l=65, r=50, b=65, t=90))
rx.plotly(data=plotly_surface_fig, width="100%")Für jedes Datum werden Eröffnungs-, Höchst-, Tiefst- und Schlusskurs als eine Kerze gezeichnet. Der Körper reicht vom Eröffnungs- zum Schlusskurs, der Docht vom Tiefst- zum Höchstkurs.
import plotly.graph_objects as go
plotly_candle_fig = go.Figure(go.Candlestick(
x=["2024-01-02", "2024-01-03", "2024-01-04", "2024-01-05", "2024-01-08", "2024-01-09"],
open=[187.15, 184.22, 182.15, 181.99, 182.09, 183.92],
high=[188.44, 185.88, 183.09, 182.76, 185.60, 185.15],
low=[183.89, 183.43, 180.88, 180.17, 181.50, 182.73],
close=[185.64, 184.25, 181.91, 181.18, 185.56, 185.14],
))
plotly_candle_fig.update_layout(title=dict(text="Stock price"), yaxis=dict(title=dict(text="USD")))
rx.plotly(data=plotly_candle_fig, width="100%")Zeigt, wie sich ein Anfangswert über hinzukommende und abgezogene Posten verändert. Mit measure legst du fest, ob ein Posten eine Veränderung ("relative") oder eine Summe ("total") ist.
import plotly.graph_objects as go
plotly_waterfall_fig = go.Figure(go.Waterfall(
name="2018",
orientation="v",
measure=["relative", "relative", "total", "relative", "relative", "total"],
x=["Sales", "Consulting", "Net revenue", "Purchases", "Other expenses", "Profit before tax"],
textposition="outside",
text=["+60", "+80", "", "-40", "-20", "Total"],
y=[60, 80, 0, -40, -20, 0],
connector={"line": {"color": "rgb(63, 63, 63)"}},
))
plotly_waterfall_fig.update_layout(title="Profit and loss statement 2018", showlegend=True)
rx.plotly(data=plotly_waterfall_fig, width="100%")Ein kleiner Balken als Ersatz für ein Messinstrument. go.Indicator bekommt gauge.shape="bullet" und vereint Ist-Balken, Bereiche (steps) und Ziellinie (threshold) in einer Zeile.
import plotly.graph_objects as go
plotly_bullet_fig = go.Figure(go.Indicator(
mode="number+gauge+delta",
value=180,
delta={"reference": 200},
domain={"x": [0.25, 1], "y": [0.4, 0.6]},
title={"text": "Revenue"},
gauge={
"shape": "bullet",
"axis": {"range": [None, 300]},
"threshold": {"line": {"color": "black", "width": 2}, "thickness": 0.75, "value": 170},
"steps": [{"range": [0, 150], "color": "gray"}, {"range": [150, 250], "color": "lightgray"}],
"bar": {"color": "black"},
},
))
plotly_bullet_fig.update_layout(height=250)
rx.plotly(data=plotly_bullet_fig, width="100%")Der Fehler wird statt mit Balken als blasses Band um die Linie gezeigt. Die obere Grenze läuft vorwärts, die untere rückwärts; so entsteht eine geschlossene Linie, deren Inneres fill="toself" füllt.
import plotly.graph_objects as go
plotly_band_x = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
plotly_band_y = [1, 2, 7, 4, 5, 6, 7, 8, 9, 10]
plotly_band_upper = [2, 3, 8, 5, 6, 7, 8, 9, 10, 11]
plotly_band_lower = [0, 1, 5, 3, 4, 5, 6, 7, 8, 9]
plotly_band_fig = go.Figure([
go.Scatter(x=plotly_band_x, y=plotly_band_y, line=dict(color="rgb(0,100,80)"), mode="lines"),
go.Scatter(
x=plotly_band_x + plotly_band_x[::-1],
y=plotly_band_upper + plotly_band_lower[::-1],
fill="toself",
fillcolor="rgba(0,100,80,0.2)",
line=dict(color="rgba(255,255,255,0)"),
hoverinfo="skip",
showlegend=False,
),
])
rx.plotly(data=plotly_band_fig, width="100%")Plotly-Karten holen beim Zeichnen Kartendaten von externen Servern: Umrisskarten (Scattergeo, Choropleth) nutzen Geodaten aus dem Plotly-CDN, Kachelkarten (Scattermap) einen Kachelserver. Dieser Kurs lädt keine externen Ressourcen, deshalb steht hier nur Code. In deiner App funktioniert er unverändert.
Die Einstellungen einer Umrisskarte stehen in layout.geo der Figure, und mit update_geos änderst du Darstellungen wie Seen und Flüsse.
import plotly.graph_objects as go
geo_fig = go.Figure(go.Scattergeo())
geo_fig.update_geos(
visible=False,
resolution=50,
showlakes=True,
lakecolor="Blue",
showrivers=True,
rivercolor="Blue",
)
geo_fig.update_layout(height=300, margin={"r": 0, "t": 0, "l": 0, "b": 0})
def geo_map_chart():
return rx.plotly(data=geo_fig, width="100%")Punkte auf einer Kachelkarte. Die offizielle Doku nimmt px.scatter_map, mit go ist es go.Scattermap. Das Aussehen der Karte legst du in layout.map fest.
import plotly.graph_objects as go
map_fig = go.Figure(go.Scattermap(
lat=[37.57, 35.18, 35.87],
lon=[126.98, 129.08, 128.60],
text=["Seoul", "Busan", "Daegu"],
mode="markers",
marker={"size": [18, 12, 10]},
))
map_fig.update_layout(
map={"style": "open-street-map", "center": {"lat": 36.4, "lon": 127.8}, "zoom": 5},
margin={"r": 0, "t": 0, "l": 0, "b": 0},
)
def scatter_map_chart():
return rx.plotly(data=map_fig, width="100%")go.Table bekommt in header die Spaltennamen und in cells je Spalte eine Liste von Werten. Scrollen und Umsortieren der Spalten funktionieren.
import plotly.graph_objects as go
plotly_table_fig = go.Figure(go.Table(
header=dict(values=["A Scores", "B Scores"]),
cells=dict(values=[[100, 90, 80, 90], [95, 85, 75, 95]]),
))
rx.plotly(data=plotly_table_fig, width="100%")Zeigt Flussmengen über die Breite von Bändern. In node.label stehen die Knotennamen, und in link verbindest du source→target über die Indizes der Knoten.
import plotly.graph_objects as go
plotly_sankey_fig = go.Figure(go.Sankey(
node=dict(pad=15, thickness=20, line=dict(color="black", width=0.5), label=["A1", "A2", "B1", "B2", "C1", "C2"], color="blue"),
link=dict(source=[0, 1, 0, 2, 3, 3], target=[2, 3, 3, 4, 4, 5], value=[8, 4, 2, 8, 4, 2]),
))
plotly_sankey_fig.update_layout(title_text="Basic Sankey Diagram", font_size=10)
rx.plotly(data=plotly_sankey_fig, width="100%")go.Scatter3d trägt die Beziehung dreier Werte im Raum ab (px.scatter_3d).
import random
import plotly.graph_objects as go
plotly_s3d_rng = random.Random(2)
plotly_s3d_fig = go.Figure([
go.Scatter3d(
x=[plotly_s3d_rng.gauss(cx, 0.4) for _ in range(30)],
y=[plotly_s3d_rng.gauss(cy, 0.3) for _ in range(30)],
z=[plotly_s3d_rng.gauss(cz, 0.3) for _ in range(30)],
mode="markers",
marker={"size": 4},
name=name,
)
for name, cx, cy, cz in [("A", 5.0, 3.4, 0.2), ("B", 5.9, 2.8, 1.3), ("C", 6.6, 3.0, 2.0)]
])
rx.plotly(data=plotly_s3d_fig, width="100%")Bei 3D-Figures liegen die Achsen in scene. Für jede Achse, etwa scene.xaxis, legst du nticks (Anzahl der Skalenstriche) und range (Bereich) fest. Die offizielle Doku nutzt Zufallszahlen von numpy, hier erledigt random dasselbe.
import random
import plotly.graph_objects as go
plotly_mesh_rng = random.Random(1)
plotly_mesh_fig = go.Figure(go.Mesh3d(
x=[70 * plotly_mesh_rng.gauss(0, 1) for _ in range(70)],
y=[55 * plotly_mesh_rng.gauss(0, 1) for _ in range(70)],
z=[40 * plotly_mesh_rng.gauss(0, 1) for _ in range(70)],
opacity=0.5,
color="rgba(244,22,100,0.6)",
))
plotly_mesh_fig.update_layout(
scene=dict(
xaxis=dict(nticks=4, range=[-100, 100]),
yaxis=dict(nticks=4, range=[-50, 100]),
zaxis=dict(nticks=4, range=[-100, 100]),
),
margin=dict(r=20, l=10, b=10, t=10),
)
rx.plotly(data=plotly_mesh_fig, width="100%")Liegt die Figure in einem State-Wert, kannst du sie zur Laufzeit ändern. Die offizielle Doku legt eine go.Figure in eine State-Variable; hier liegt im State nur eine Zahl, und eine berechnete @rx.var erzeugt die Figure. Bewegst du den Schieberegler, wird der berechnete Wert neu erzeugt und das Diagramm ändert sich.
import math
import plotly.graph_objects as go
class PlotlyWaveState(rx.State):
cycles: int = 2
@rx.event
def set_cycles(self, value: list[float]):
self.cycles = int(value[0])
@rx.var
def figure(self) -> go.Figure:
xs = [i / 50 for i in range(101)]
fig = go.Figure(go.Scatter(x=xs, y=[math.sin(2 * math.pi * self.cycles * x) for x in xs], mode="lines"))
fig.update_layout(title=f"{self.cycles} cycles", height=300)
return fig
rx.vstack(
rx.slider(value=[PlotlyWaveState.cycles], min=1, max=8, step=1, on_change=PlotlyWaveState.set_cycles, width="240px"),
rx.plotly(data=PlotlyWaveState.figure, width="100%"),
width="100%",
)on_click, on_hover und on_selected übergeben die Liste der Punkte, an denen das Event auftrat. Jeder Punkt enthält Werte wie x, y, curveNumber (die wievielte trace) und pointNumber (der wievielte Punkt).
import plotly.graph_objects as go
plotly_click_fig = go.Figure(go.Bar(x=["Mon", "Tue", "Wed", "Thu", "Fri"], y=[12, 19, 7, 15, 22]))
plotly_click_fig.update_layout(height=280)
class PlotlyClickState(rx.State):
picked: str = "Click a bar"
@rx.event
def pick(self, points: list[dict]):
if points:
point = points[0]
self.picked = f"{point['x']}: {point['y']}"
rx.vstack(
rx.plotly(data=plotly_click_fig, on_click=PlotlyClickState.pick, width="100%"),
rx.badge(PlotlyClickState.picked, size="2"),
width="100%",
)Das Aussehen legst du beim Erstellen der Figure mit update_layout() fest. Alle Layout-Eigenschaften wie Titelposition (title_x), Hintergrundfarben von Plot und Umgebung oder Schriften findest du in der Plotly-Layout-Doku.
Statt Breite und Höhe von rx.plotly fest vorzugeben, lässt du es besser der Größe des äußeren Containers folgen. Dann wächst und schrumpft es mit der Bildschirmgröße.
import plotly.graph_objects as go
plotly_styled_fig = go.Figure(go.Scatter(
x=[1952, 1957, 1962, 1967, 1972, 1977, 1982, 1987, 1992, 1997, 2002, 2007],
y=[68.75, 69.96, 71.3, 72.13, 72.88, 74.21, 75.76, 76.86, 77.95, 78.61, 79.77, 80.65],
mode="lines",
name="Canada",
))
plotly_styled_fig.update_layout(
title="Life expectancy in Canada",
title_x=0.5,
plot_bgcolor="#c3d7f7",
paper_bgcolor="rgba(128, 128, 128, 0.1)",
showlegend=True,
title_font_family="Open Sans",
title_font_size=25,
)
rx.plotly(data=plotly_styled_fig, width="100%")Reflex 0.10 hat auch schlanke Pakete, die nur die nötigen traces enthalten. rx.plotly.basic, rx.plotly.cartesian, rx.plotly.finance, rx.plotly.geo, rx.plotly.gl2d, rx.plotly.gl3d, rx.plotly.mapbox und rx.plotly.strict nehmen dieselben Props wie rx.plotly an und verringern die Datenmenge, die der Browser herunterlädt (in der offiziellen Doku stehen sie noch nicht).
Im State liegt nur der Name des gewählten Produkts, und ein berechneter Wert zeichnet monatliche Balken und eine kumulierte Linie zusammen. Die kumulierte Linie gehört zur rechten Achse (yaxis2), und hovermode="x unified" fasst die Werte eines Monats in einem Kästchen zusammen.
import plotly.graph_objects as go
plotly_months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
plotly_sales = {
"Chairs": [32, 41, 38, 52, 61, 58, 70, 66, 59, 73, 88, 95],
"Tables": [12, 15, 21, 19, 24, 30, 28, 33, 35, 31, 40, 46],
"Lamps": [55, 50, 47, 44, 49, 53, 60, 58, 62, 67, 80, 102],
}
class PlotlyOrderState(rx.State):
product: str = "Chairs"
@rx.event
def set_product(self, value: str):
self.product = value
@rx.var
def figure(self) -> go.Figure:
monthly = plotly_sales[self.product]
running = [sum(monthly[: i + 1]) for i in range(len(monthly))]
fig = go.Figure([
go.Bar(x=plotly_months, y=monthly, name="Monthly"),
go.Scatter(x=plotly_months, y=running, name="Running total", yaxis="y2", mode="lines+markers"),
])
fig.update_layout(
title=f"{self.product} sales",
hovermode="x unified",
yaxis2={"overlaying": "y", "side": "right"},
legend={"orientation": "h", "y": -0.2},
height=360,
)
return fig
rx.vstack(
rx.select(["Chairs", "Tables", "Lamps"], value=PlotlyOrderState.product, on_change=PlotlyOrderState.set_product),
rx.plotly(data=PlotlyOrderState.figure, width="100%"),
width="100%",
)Werkstattnotizen
Statt fig.show() schreibst du rx.plotly(data=fig). Mit go oder mit px erstellte Figures funktionieren gleich.
layout=dict überschreibt das Layout, locale ändert Zahlenformat und Sprache der Werkzeugleiste.
Im State liegen einfache Werte; gibt eine berechnete @rx.var eine go.Figure zurück, folgt das Diagramm.
on_click, on_hover und on_selected übergeben eine Punktliste (x, y, curveNumber, pointNumber …).
Karten laden externe Kartendaten. Das Theme wechselt automatisch mit hellem und dunklem Modus.
Über neue Lektionen informiert werden
Wir schicken dir eine E-Mail, wenn dieser Kurs neue Lektionen bekommt oder ein Folgekurs erscheint.
R
ReflexKR
Python und Reflex zum Anfassen. Alle Beispiele wurden mit Reflex 0.10.0 ausgeführt und geprüft.
ReflexKR ist kostenlos und ohne Werbebanner. Wenn es dir geholfen hat, kannst du es mit einem Kaffee unterstützen. ☕ Spendier uns einen Kaffee
Hinweis zu Affiliate-Links© 2026 ReflexKR · Since 2026 · CC BY-NC 4.0
Fragen & Antworten
Frag alles zu dieser Lektion. Fragen aus allen Sprachversionen dieser Seite erscheinen hier gemeinsam.