R

ReflexKR

Reflex-Dokumentation

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

Die Komponentenwerkstatt: Reflex' 100 Bibliotheksbausteine
Andere Diagrammbibliotheken

Plotly

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.

Props ausprobieren

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%",
)
layout überschreibt das Layout der Figure; locale ändert das Zahlenformat und die Hinweistexte der Werkzeugleiste oben rechts.
PropWerteStandardVerwendung
datago.Figure oder deren dict-Die zu zeichnende Figure. Auch ein State-Wert geht
layoutdict-Werte, die das Layout der Figure überschreiben
templatePlotly-Templateheller Modus plotly, dunkler Modus plotly_darkTheme für alle Farben und Schriften
configdict-Plotly-Einstellungen wie Werkzeugleiste oder Scroll-Zoom
locale"de" "ko" …-Sprache für Zahlen- und Datumsformat und die Texte der Werkzeugleiste
use_resize_handlerTrue / FalseTrueBei geänderter Fenstergröße neu anpassen
on_click · on_hover · on_unhover · on_selected · on_selectingEvent-Ü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.

Verschiedene Diagramme

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.

Balkendiagramm

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%")

Streudiagramm

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%")

Kreisdiagramm

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%")

Heatmap

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%")

Histogramm

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%")

Boxplot

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%")

Blasendiagramm

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%")

Gantt-Diagramm

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%")

Sunburst-Diagramm

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%")

Trichterdiagramm

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%")

Sprache und Zahlenformat: locale

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%")

3D-Oberfläche

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%")

Finanzdiagramme

Candlestick

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%")

Wasserfalldiagramm

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%")

Bullet-Diagramm

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%")

Statistikdiagramm: kontinuierliches Fehlerband

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%")

Karten (nur Code)

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.

Umrisskarte

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%")

Punktkarte

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%")

Tabellen und Flussdiagramme

Tabelle

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%")

Sankey-Diagramm

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%")

3D-Diagramme

3D-Streudiagramm

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%")

3D-Achsen

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%")

Figures über den State ändern

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%",
)

Angeklickte Punkte empfangen

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).

Click a bar
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%",
)

Gestaltung und Layout

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).

Auftrag erledigt

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.

← Zurück

Diagrammbausteine · Brush

Weiter →

Andere Diagrammbibliotheken · Pyplot

Über neue Lektionen informiert werden

Wir schicken dir eine E-Mail, wenn dieser Kurs neue Lektionen bekommt oder ein Folgekurs erscheint.

Erhoben: deine E-Mail-Adresse · Zweck: Hinweise auf neue Lektionen oder den Start dieses Kurses · Speicherdauer: bis du die Löschung verlangst. Keine andere Nutzung, keine Weitergabe. Antworte einfach auf eine Benachrichtigung, dann löschen wir sie sofort.

Fragen & Antworten

Frag alles zu dieser Lektion. Fragen aus allen Sprachversionen dieser Seite erscheinen hier gemeinsam.

Wird als reiner Text angezeigt, ohne Links oder Formatierung.

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
한국어English日本語简体中文EspañolDeutsch

© 2026 ReflexKR · Since 2026 · CC BY-NC 4.0

Built with Reflex