Kurs
Plotly ist eine der leistungsstärksten und beliebtesten Python-Bibliotheken zur Erstellung interaktiver Diagramme. Die Erstellung einfacher Diagramme mit Plotly ist zwar einfach, aber wirklich aussagekräftige Datenvisualisierungen erfordern oft zusätzliche Elemente, die die Aufmerksamkeit des Betrachters lenken und wichtigen Kontext liefern. Hier sind die Plotly-Formen von unschätzbarem Wert.
Formen sind grafische Elemente wie Rechtecke, Linien und Kreise, die du auf deine Plotly-Zahlen zeichnen kannst, um sie zu kommentieren, hervorzuheben und wichtigen Kontext hinzuzufügen. Sie sind der Schlüssel, um einen Standardplot in eine reichhaltige, aufschlussreiche und publikationsfähige Visualisierung zu verwandeln.
Bild vom Autor
In diesem Artikel erfährst du alles, was du über Plotly Shapes wissen musst, von der grundlegenden Implementierung bis hin zu fortgeschrittenen Anpassungsmethoden. Für diejenigen, die neu in Plotly sind, ist es ein guter erster Schritt, sich mit der Benutzeroberfläche vertraut zu machen, und dieser Einführung in die Datenvisualisierung mit Plotly in Python kann dir helfen, die Grundlagen zu beherrschen, bevor du dich mit tieferen Anpassungen wie Shapes beschäftigst.
Was sind Plotly-Formen?
Plotly Shapes sind Vektorgrafiken, die auf eine Figur gezeichnet werden, um zusätzlichen Kontext zu liefern oder bestimmte Bereiche hervorzuheben. Diese Anmerkungen sind wichtig, um Diagramme zu erstellen, die nicht nur optisch ansprechend, sondern auch reich an Informationen sind.
Die Bedeutung von Formen in der Datenvisualisierung
Bei der Datenvisualisierung ist Klarheit wichtig. Während Diagramme wie Streuungsdiagramme oder Balkendiagramme die Daten präsentieren, helfen Formen, die Geschichte hinter den Daten zu erzählen. Sie haben zwei Hauptfunktionen:
- Aufzeigen von Datentrends: Formen können die Aufmerksamkeit auf wichtige Zeiträume oder Ereignisse in deinen Daten lenken. Du könntest z. B. ein Rechteck verwenden, um eine Rezessionsperiode in einer Zeitreihengrafik des BIP zu schattieren oder eine Linie zu ziehen, um eine wichtige politische Änderung zu markieren. Dieser visuelle Hinweis hilft dem Betrachter, die Auswirkungen externer Faktoren auf die Daten sofort zu erfassen.
- Bereitstellung von kontextbezogenen Anmerkungen: Formen können bestimmte Datenpunkte oder -cluster einkreisen oder darauf hinweisen, z. B. Ausreißer, Interessengruppen oder kritische Schwellenwerte. Stell dir eine Qualitätskontrollkarte vor, in der du Messwerte, die außerhalb der zulässigen Grenzen liegen, mit Kreisen kennzeichnest. Das macht die Auswertung der Daten schneller und intuitiver.
Wenn du einen schnellen Überblick über die gebräuchlichsten Datenvisualisierungen, den richtigen Zeitpunkt für ihren Einsatz und ihre häufigsten Anwendungsfälle haben möchtest, schau dir unseren Spickzettel zur Datenvisualisierung.
Übersicht über die Shape-Typen in Plotly
Plotly unterstützt verschiedene geometrische Formen, die dem Layout einer Figur hinzugefügt werden können. Jeder wird durch seine type
und spezifische Koordinatenparameter definiert.
Hier ist ein kurzer Blick auf die Hauptformen:
- Rectangle (
type: 'rect'
): Definiert durch zwei gegenüberliegende Ecken (x0
,y0
) und (x1
,y1
). Rechtecke eignen sich perfekt, um interessante Bereiche zu schattieren oder ein bestimmtes Datenfenster hervorzuheben. - Zeile (
type: 'line'
): Definiert durch einen Startpunkt (x0
,y0
) und einen Endpunkt (x1
,y1
). Linien eignen sich hervorragend zum Erstellen von Trendlinien, Schwellenwerten oder Referenzmarken. - Kreis (
type: 'circle'
): Definiert durch einen Mittelpunkt (x0
,y0
) und einen Radius. Kreise sind ideal, um einzelne Datenpunkte oder kleine Cluster hervorzuheben. Beachte, dass du beim Erstellen eines Kreises oft ein gleiches Seitenverhältnis für die Achsen festlegen musst (fig.update_layout(yaxis_scaleanchor="x")
), damit er nicht wie ein Oval aussieht. - Pfad (
type: 'path'
): Definiert durch einen SVG-Pfad-String. Mit Pfaden kannst du komplexe Freiformen, einschließlich Polygone, zeichnen. Du gibst eine Abfolge von Befehlen ein (z.B.M
für Verschieben,L
für Linie zu,Z
für Pfad schließen), um jede beliebige Form zu zeichnen, die du brauchst. Dies ist die vielseitigste Option für die Erstellung benutzerdefinierter geometrischer Beschriftungen.
Das Verständnis dieser Grundtypen ist der erste Schritt zur Beherrschung visueller Anmerkungen in deinen Plotly-Zahlen.
Hinzufügen von Formen zu Plotly-Diagrammen
Um Plotly Shapes in deine Visualisierungen zu implementieren, musst du zwei primäre Ansätze verstehen: die add_shape()
Methode für einzelne Shapes und den update_layout()
Ansatz für mehrere Shapes. Beide Methoden bieten einzigartige Vorteile, abhängig von deinem speziellen Anwendungsfall und deinen Workflow-Präferenzen. Sehen wir uns an, wie du mit der Methode add_shape()
Formen hinzufügen kannst.
Wie kann ich mit add_shape() Formen hinzufügen?
Die wichtigste Methode zum Hinzufügen einer einzelnen Form zu einer Plotly-Figur ist fig.add_shape()
. Die Methode add_shape()
ist eine Funktion des plotly.graph_objects.Figure
Objekts. Du erstellst zunächst deine Basisfigur (z. B. ein Streudiagramm oder ein Liniendiagramm) und rufst dann diese Methode auf, um die Form darüber zu legen.
Dies ist besonders nützlich, wenn du Formen auf der Grundlage bestimmter Bedingungen oder Datenwerte programmatisch hinzufügen musst. Schauen wir uns ein einfaches Beispiel an, bei dem wir eine bestimmte Region in einer Zeitreihengrafik hervorheben.
import plotly.graph_objects as go
import numpy as np
# Create sample data
x = np.linspace(0, 10, 100)
y = np.sin(x) + np.random.normal(0, 0.1, 100)
# Create base figure
fig = go.Figure()
fig.add_trace(go.Scatter(x=x, y=y, mode='lines', name='Signal'))
# Add a shape using add_shape method
fig.add_shape(
type="rect", # Shape type
x0=2, x1=4, # X coordinates
y0=-2, y1=2, # Y coordinates
fillcolor="rgba(255, 0, 0, 0.3)", # Fill color with transparency
line=dict(color="red", width=2) # Border styling
)
fig.show()
Ausgabe:
Die Funktionalität von Plotly add_shape()
wird besonders leistungsfähig, wenn du das Koordinatensystem verstehst. Formen können sich mit den Parametern xref
und yref
auf verschiedene Koordinatensysteme beziehen. Ändern wir das obige Diagramm mit diesen Parametern wie unten gezeigt:
# Shape referenced to data coordinates (default)
fig.add_shape(type="line", x0=1, x1=9, y0=0, y1=0,
line=dict(color="green", width=3))
# Shape referenced to paper coordinates (0-1 scale)
fig.add_shape(type="rect", xref="paper", yref="paper",
x0=0.1, x1=0.9, y0=0.1, y1=0.9,
fillcolor="rgba(0, 0, 255, 0.1)")
Ausgabe:
Rechtecke und Linien anpassen
Rechtecke und Linien sind die am häufigsten verwendeten Formen für Anmerkungen. Plotly bietet umfangreiche Anpassungsmöglichkeiten, um ihr Aussehen zu kontrollieren. Als schnelle Referenz für die gängige Plotly-Syntax ist das Plotly Express Cheat Sheet eine unschätzbare Ressource. Schauen wir uns an, wie du diese Formen anpassen kannst.
Anpassung der Rechteckform
Rechtecke werden durch zwei Punkte (x0
,y0
und x1
, y1
) definiert. Du kannst die Füllung und den Rahmen separat gestalten.
# Advanced rectangle customization
fig.add_shape(
type="rect",
x0=3, x1=7,
y0=-1.5, y1=1.5,
# Fill properties
fillcolor="rgba(50, 171, 96, 0.4)",
# Line properties
line=dict(
color="darkgreen",
width=3,
dash="dashdot" # Options: solid, dot, dash, longdash, dashdot
),
# Layer control
layer="below" # Options: above, below
)
Ausgabe:
Anpassung der Linienform
Linien können mit den speziellen Methoden "add_hline" und "add_vline" für horizontale und vertikale Linien, die sich über den gesamten Plot erstrecken, oder mit der allgemeinen Methode "add_shape" für eine genauere Steuerung hinzugefügt werden. Schauen wir uns ein Beispiel an:
# Horizontal threshold lines
fig.add_hline(y=1.0, line_dash="dash", line_color="red",
annotation_text="Upper Threshold")
fig.add_hline(y=-1.0, line_dash="dash", line_color="red",
annotation_text="Lower Threshold")
# Custom diagonal line
fig.add_shape(
type="line",
x0=0, x1=10,
y0=-2, y1=2,
line=dict(
color="purple",
width=4,
dash="longdashdot"
)
)
Ausgabe:
Diese Beispiele zeigen, wie einfach du grundlegende Plotly-Formen hinzufügen und gestalten kannst, um deine Diagramme informativer zu machen.
Erweiterte Konfiguration und Anpassung
Neben dem Hinzufügen von Grundformen bietet Plotly leistungsstarke Werkzeuge für die Verwaltung mehrerer Formen und die Steuerung ihrer visuellen Hierarchie. Diese fortschrittlichen Funktionen sind für die Erstellung komplexer, vielschichtiger und dynamischer Visualisierungen unerlässlich. Sehen wir uns einige Möglichkeiten an, wie du die Diagramme konfigurieren und anpassen kannst.
Plotly.update_layout für dynamische Aktualisierungen verwenden
Während sich die Methode add_shape()
perfekt eignet, um Shapes einzeln hinzuzufügen, ist die Methode update_layout()
ein effizienterer Weg, um eine Sammlung von Shapes zu verwalten, vor allem, wenn sie programmgesteuert erzeugt werden. Anstatt für jede Form eine Funktion aufzurufen, kannst du eine Liste von Formwörterbüchern direkt an das Argument shapes
in update_layout()
übergeben.
Sehen wir uns ein Beispiel für die Anwendung dieser Methode an:
import plotly.graph_objects as go
import numpy as np
# Sample scatter plot data
x_data = np.linspace(0, 10, 50)
y_data = np.sin(x_data) + np.random.normal(0, 0.1, 50)
fig = go.Figure(data=go.Scatter(x=x_data, y=y_data, mode='markers', name='Data Points'))
# Define a list of shapes to add
shapes_to_add = [
# A rectangle highlighting a peak area
dict(
type="rect",
x0=1, x1=2.5, y0=0.8, y1=1.2,
fillcolor="rgba(255, 165, 0, 0.4)",
line_width=0
),
# A vertical line marking an event
dict(
type="line",
x0=7.5, x1=7.5, y0=0, y1=1,
yref="paper", # Span the full plot height
line=dict(color="red", width=2, dash="dot")
)
]
# Add all shapes at once using update_layout
fig.update_layout(
shapes=shapes_to_add
)
fig.show()
Ausgabe:
Diese Methode ist besonders leistungsfähig für dynamische Anwendungen, wie z. B. ein Dashboard, bei dem sich die Formen aufgrund von Benutzereingaben ändern müssen. Du kannst eine neue Liste von Formobjekten erstellen und das Layout in einem einzigen, sauberen Vorgang aktualisieren. So bleibt dein Code übersichtlich und ist in der Regel leistungsfähiger, wenn du eine große Anzahl von Formen auf einmal hinzufügen willst.
Layering und z-index Kontrolle
Wenn du einem Diagramm Formen hinzufügst, ist es wichtig zu bestimmen, ob sie über oder hinter deinen Daten erscheinen. Plotly verwaltet dies über die Eigenschaft Layer. Auch wenn es sich nicht um eine granulare z-index
wie in CSS handelt, bietet sie eine wichtige Kontrolle über die visuelle Stapelung.
Die Eigenschaft layer
kann auf einen von zwei Werten eingestellt werden:
'above'
: Die Form wird über die Datenspuren gezeichnet. Dies ist die Standardeinstellung und ist nützlich für Anmerkungen, die deutlich sichtbar sein müssen.'below'
: Die Form wird unter Datenspuren und Gitternetzlinien gezeichnet. Dies ist ideal, um den Hintergrund zu schattieren oder Regionen hervorzuheben, ohne die Datenpunkte selbst zu verdecken.
Die Reihenfolge der Formen innerhalb der Formen Liste spielt ebenfalls eine Rolle: Formen, die später in der Liste definiert werden, werden über den früher definierten Formen (innerhalb derselben Ebene) gezeichnet.
Hier ist ein Beispiel, das den Effekt der Überlagerung zeigt:
import plotly.graph_objects as go
fig = go.Figure(data=go.Scatter(x=[1, 2, 3, 4, 5], y=[5, 3, 4, 2, 6], mode='markers', marker_size=20, name='Data'))
# Add a shape BELOW the data points
fig.add_shape(
type="rect",
x0=2.5, y0=2.5, x1=4.5, y1=4.5,
fillcolor="LightPink",
opacity=0.8,
layer="below", # Key parameter
line_width=0
)
# Add a shape ABOVE the data points
fig.add_shape(
type="circle",
x0=0.5, y0=4.5, x1=1.5, y1=5.5,
fillcolor="LightSeaGreen",
opacity=0.6,
layer="above", # Key parameter
line_width=0
)
fig.update_layout(
xaxis=dict(showgrid=False), # Turn off gridlines to see effect clearly
yaxis=dict(showgrid=False)
)
fig.show()
Ausgabe:
Wie du siehst, befindet sich das rosa Rechteck hinter den Markern, während der grüne Kreis den Datenpunkt überlagert.
Die Beherrschung dieser Layout- und Layering-Techniken ist ein wichtiger Bestandteil bei der Erstellung fortgeschrittener und interaktiver Datenvisualisierungen mit Plotly. Für diejenigen, die in R arbeiten, gelten ähnliche Konzepte, wie sie in Intermediate Interactive Data Visualization with Plotly in R erforscht werden.
Interaktive Bearbeitung von Formen
Eine der leistungsstärksten Funktionen von Plotly ist seine Interaktivität. Du kannst Plotly-Formen bearbeitbar machen, sodass die Nutzer sie direkt auf dem Plot ziehen, in der Größe verändern und drehen können. Diese Funktion wird durch die Einstellung editable=True
in der Definition der Form aktiviert. Sehen wir uns ein Beispiel an, wie man das macht:
import plotly.graph_objects as go
import numpy as np
# Create a scatter plot
fig = go.Figure(go.Scatter(
x=np.random.rand(100),
y=np.random.rand(100),
mode='markers'
))
# Add a draggable rectangle
fig.add_shape(
type="rect",
x0=0.2, y0=0.2, x1=0.5, y1=0.5,
line=dict(color="RoyalBlue", width=2),
fillcolor="LightSkyBlue",
opacity=0.5,
editable=True # This makes the shape interactive
)
fig.update_layout(
xaxis=dict(range=[0, 1]),
yaxis=dict(range=[0, 1]),
# The 'newshape' button in the modebar allows drawing new shapes
# The config dictionary enables editing of existing shapes
dragmode='select'
)
# To enable editing, the modebar must be visible (default)
# and the plot's config can ensure editing tools are available.
fig.show(config={'edits': {'shapePosition': True}})
Ausgabe:
Interaktive Formen sind unglaublich nützlich für die explorative Datenanalyse. Zum Beispiel kann ein/e Nutzer/in ein Rechteck über verschiedene Zeiträume ziehen, um zu sehen, wie die entsprechenden Statistiken in Echtzeit in einer Dash-App aktualisiert werden. Oder sie können die Größe eines Kreises ändern, um eine andere Gruppe von Punkten für weitere Untersuchungen auszuwählen.
Auch wenn sie sehr leistungsfähig sind, solltest du bedenken, dass die häufige Verwendung von bearbeitbaren Formen in komplexen Webanwendungen Auswirkungen auf die Leistung haben kann. Für die Entwicklung wirklich dynamischer und nutzerorientierter Tools sind sie jedoch unverzichtbar.
Die Erforschung der Interaktivität ist ein wichtiger Bestandteil der modernen Datenvisualisierung. Dieses Thema wird in Kursen wie Interaktive Datenvisualisierung mit Plotly in R behandelt, das viele Prinzipien mit seinem Python-Pendant teilt.
Integration von Plotly mit anderen Bibliotheken
Die in Plotly integrierten Formen sind zwar vielseitig, aber manchmal musst du sehr komplexe oder benutzerdefinierte Geometrien erstellen. Durch die Integration von Spezialbibliotheken wie Shapely kannst du anspruchsvolle Polygone definieren und sie als benutzerdefinierte Plotly-Shapes zu deinen Visualisierungen hinzufügen.
Shapely für fortgeschrittene geometrische Formen verwenden
Shapely ist eine leistungsstarke Python-Bibliothek für die Manipulation und Analyse von flächigen geometrischen Objekten. Es ist das Standardwerkzeug für die computergestützte Geometrie, das häufig für geografische Analysen verwendet wird. Du kannst damit komplizierte Formen erstellen, wie z.B. eine Vereinigung von zwei sich überlappenden Kreisen oder ein Polygon mit einem Loch darin, und sie dann in Plotly visualisieren.
Der Prozess umfasst zwei Hauptschritte:
- Definiere die komplexe Form mit Shapely.
- Extrahiere die Koordinaten aus dem Shapely-Objekt und formatiere sie als SVG-Pfadstring, den Plotly mit
type: 'path'
darstellen kann.
Ein SVG-Pfad-String ist eine Mini-Sprache zum Zeichnen. Er verwendet Befehle wie M
(moveto), um einen Startpunkt zu setzen, L
(lineto), um eine Linie zu einem neuen Punkt zu ziehen, und Z
, um den Pfad zu schließen, indem er eine Linie zurück zum Startpunkt zieht.
Sehen wir uns an, wie du ein Polygon mit einem Ausschnitt erstellst und es zu einer Plotly-Figur hinzufügst.
import plotly.graph_objects as go
from shapely.geometry import Polygon
# 1. Create a complex shape using Shapely
# An outer rectangle
outer_coords = [(1, 1), (1, 5), (8, 5), (8, 1)]
# An inner rectangle (this will be the "hole")
inner_coords = [(3, 2), (3, 4), (6, 4), (6, 2)]
# Define the polygon with a hole
polygon_with_hole = Polygon(outer_coords, [inner_coords])
# 2. Extract coordinates and build the SVG path string
# The exterior path
exterior_x, exterior_y = polygon_with_hole.exterior.xy
path = f"M {exterior_x[0]} {exterior_y[0]}"
for x, y in zip(exterior_x[1:], exterior_y[1:]):
path += f" L {x} {y}"
path += " Z" # Close the exterior path
# The interior path (the hole)
interior_x, interior_y = polygon_with_hole.interiors[0].xy
path += f" M {interior_x[0]} {interior_y[0]}"
for x, y in zip(interior_x[1:], interior_y[1:]):
path += f" L {x} {y}"
path += " Z" # Close the interior path
# Create a figure
fig = go.Figure()
# Add the complex shape to the figure
fig.add_shape(
type="path",
path=path,
fillcolor="LightSeaGreen",
opacity=0.7,
line_color="DarkSlateGray"
)
# You can add data to see how the shape interacts with it
fig.add_trace(go.Scatter(
x=[2, 7, 4.5],
y=[3, 3, 1.5],
mode='markers',
marker=dict(size=15, color='DarkRed')
))
# Use scaleanchor to ensure the shape's aspect ratio is preserved
fig.update_yaxes(scaleanchor="x", scaleratio=1)
fig.show()
Ausgabe:
Diese Technik ist von unschätzbarem Wert für geografische Anwendungen, z. B. für die Darstellung von Verkaufsgebieten oder in wissenschaftlichen Kontexten, wo du unregelmäßige Bereiche von Interesse hervorheben musst.
Zu verstehen, wie verschiedene Arten von Datendiagrammen erstellt werden und wie sie mit solchen Tools verbessert werden können, ist eine grundlegende Fähigkeit für jeden Datenpraktiker. Mehr über die verschiedenen Plot-Typen erfährst du in dieser Anleitung, wie du sie in Python erstellst.
Styling und ästhetische Anpassung
Die Standarddarstellung von Plotly Shapes ist funktional, aber die Anpassung ihres Stils ist wichtig, um eine ausgefeilte und professionell aussehende Visualisierung zu erstellen. Der durchdachte Einsatz von Farbe, Deckkraft und Füllungen kann die Lesbarkeit und Ästhetik deutlich verbessern.
Farbe, Deckkraft und Musterfüllungen
Mit Plotly kannst du das Aussehen der Formen genau steuern und sie an das Farbschema und die Designsprache deines Plots anpassen.
Für eine präzise Steuerung von Farbe und Transparenz wird die Verwendung der RGBA-Farbspezifikation (Rot, Grün, Blau, Alpha) dringend empfohlen. Der a
(Alpha)-Kanal steuert die Deckkraft, wobei ein Wert von 1
völlig undurchsichtig und 0
völlig transparent ist.
Das ist wichtig, um nicht aufdringliche Hervorhebungen zu erstellen, bei denen die Form den Kontext hinzufügt, ohne die Daten darunter vollständig zu verbergen. Du kannst RGBA-Werte als String wie 'rgba(255, 99, 71, 0.5)'
angeben. Sehen wir uns ein Beispiel an:
import plotly.graph_objects as go
import numpy as np
# Create sample data for styling demonstration
x = np.linspace(0, 10, 100)
y1 = np.sin(x) + np.random.normal(0, 0.1, 100)
y2 = np.cos(x) + np.random.normal(0, 0.1, 100)
fig = go.Figure()
fig.add_trace(go.Scatter(x=x, y=y1, name='Signal 1', line=dict(color='blue')))
fig.add_trace(go.Scatter(x=x, y=y2, name='Signal 2', line=dict(color='red')))
# RGBA Color Technique 1: Graduated opacity for depth
opacity_levels = [0.15, 0.25, 0.35]
colors = ['255,0,0', '0,255,0', '0,0,255']
for i, (opacity, color) in enumerate(zip(opacity_levels, colors)):
fig.add_shape(
type="rect",
x0=i*2.5, x1=(i+1)*2.5,
y0=-3, y1=3,
fillcolor=f"rgba({color},{opacity})",
line=dict(color=f"rgb({color})", width=2),
layer="below"
)
# RGBA Technique 2: Color blending for overlapping regions
fig.add_shape(
type="circle",
x0=7.5, x1=9.5,
y0=-1, y1=1,
fillcolor="rgba(255, 255, 0, 0.4)", # Semi-transparent yellow
line=dict(color="orange", width=3),
layer="below"
)
fig.update_layout(
title="Advanced RGBA Color Techniques in Plotly Shapes",
showlegend=True
)
fig.show()
Ausgabe:
Strategien zur Simulation von Musterfüllungen
Plotly unterstützt zwar von Haus aus keine Musterfüllungen, aber Datenpraktiker können mit kreativen Techniken komplexe Füllmuster simulieren. Wir können zum Beispiel mit einer Funktion wie der folgenden Muster im Diagramm erstellen:
def create_pattern_fill_simulation(fig, x0, x1, y0, y1, pattern_type='diagonal'):
"""Simulate pattern fills using multiple overlapping shapes"""
if pattern_type == 'diagonal':
# Create diagonal line pattern
line_spacing = 0.2
line_width = 1
# Calculate diagonal lines
range_x = x1 - x0
range_y = y1 - y0
num_lines = int((range_x + range_y) / line_spacing)
for i in range(num_lines):
offset = i * line_spacing
# Calculate line endpoints for diagonal pattern
start_x = max(x0, x0 + offset - range_y)
start_y = max(y0, y1 - offset)
end_x = min(x1, x0 + offset)
end_y = min(y1, y1 - offset + range_x)
fig.add_shape(
type="line",
x0=start_x, x1=end_x,
y0=start_y, y1=end_y,
line=dict(color="rgba(0, 0, 0, 0.3)", width=line_width),
layer="above"
)
elif pattern_type == 'crosshatch':
# Create crosshatch pattern
spacing = 0.3
# Vertical lines
x_lines = np.arange(x0, x1, spacing)
for x_line in x_lines:
fig.add_shape(
type="line",
x0=x_line, x1=x_line,
y0=y0, y1=y1,
line=dict(color="rgba(100, 100, 100, 0.4)", width=1),
layer="above"
)
# Horizontal lines
y_lines = np.arange(y0, y1, spacing)
for y_line in y_lines:
fig.add_shape(
type="line",
x0=x0, x1=x1,
y0=y_line, y1=y_line,
line=dict(color="rgba(100, 100, 100, 0.4)", width=1),
layer="above"
)
return fig
# Demonstration of pattern fill simulation
pattern_fig = go.Figure()
pattern_fig.add_trace(go.Scatter(x=[1, 2, 3, 4, 5], y=[2, 4, 3, 5, 1],
mode='lines+markers', name='Data'))
# Add base rectangle
pattern_fig.add_shape(
type="rect",
x0=1.5, x1=3.5,
y0=1, y1=5,
fillcolor="rgba(200, 200, 255, 0.3)",
line=dict(color="blue", width=2),
layer="below"
)
# Apply pattern fill simulation
pattern_fig = create_pattern_fill_simulation(pattern_fig, 1.5, 3.5, 1, 5, 'diagonal')
pattern_fig.show()
Simulation des Gradienten-Effekts
Um verlaufsähnliche Effekte zu erzeugen, musst du mehrere Formen mit unterschiedlicher Deckkraft strategisch übereinanderlegen. Wir können die gleiche Strategie wie bei der Erstellung der Muster anwenden, wie unten gezeigt:
def create_gradient_effect(fig, x0, x1, y0, y1, start_color, end_color, num_bands=20):
"""Simulate gradient fill using multiple rectangular bands"""
# Parse RGB values from color strings
def parse_rgb(color_str):
if color_str.startswith('rgb('):
values = color_str[4:-1].split(',')
return [int(v.strip()) for v in values]
return [0, 0, 0] # Default to black if parsing fails
start_rgb = parse_rgb(start_color) if isinstance(start_color, str) else start_color
end_rgb = parse_rgb(end_color) if isinstance(end_color, str) else end_color
band_height = (y1 - y0) / num_bands
for i in range(num_bands):
# Calculate interpolated color
ratio = i / (num_bands - 1)
r = int(start_rgb[0] + (end_rgb[0] - start_rgb[0]) * ratio)
g = int(start_rgb[1] + (end_rgb[1] - start_rgb[1]) * ratio)
b = int(start_rgb[2] + (end_rgb[2] - start_rgb[2]) * ratio)
# Calculate band position
band_y0 = y0 + i * band_height
band_y1 = band_y0 + band_height
fig.add_shape(
type="rect",
x0=x0, x1=x1,
y0=band_y0, y1=band_y1,
fillcolor=f"rgba({r}, {g}, {b}, 0.7)",
line=dict(width=0), # No border for seamless gradient
layer="below"
)
return fig
# Apply gradient effect
gradient_fig = go.Figure()
gradient_fig.add_trace(go.Scatter(x=list(range(10)),
y=np.random.randn(10).cumsum(),
mode='lines', name='Time Series'))
gradient_fig = create_gradient_effect(
gradient_fig, 2, 8, -3, 3,
[255, 0, 0], [0, 0, 255], # Red to blue gradient
num_bands=30
)
gradient_fig.show()
Ausgabe:
Fehlersuche und Optimierung
Obwohl das Hinzufügen von Plotly-Formen im Allgemeinen einfach ist, kann es zu Problemen mit der Ausrichtung oder der Leistung kommen, vor allem bei komplexen Diagrammen. Wenn du diese häufigen Fallstricke kennst und weißt, wie du sie umgehen kannst, wirst du viel Zeit und Mühe sparen.
Häufige Probleme mit der Formausrichtung
Eine der häufigsten Herausforderungen ist es, die Formen genau dort erscheinen zu lassen, wo du sie haben willst. Eine Linie, die sich über die gesamte Breite des Plots erstrecken soll, könnte nicht ausreichen, oder ein Rechteck könnte nicht wie erwartet an den Rasterlinien ausgerichtet werden. Diese Probleme sind fast immer auf eine falsche Koordinatenreferenzierung zurückzuführen.
Plotly verwendet zwei Koordinatensysteme zum Platzieren von Formen:
- Datenkoordinaten (
xref: 'x', yref: 'y'
): Dies ist die Standardeinstellung. Die Position der Form ist an die Werte auf der x- und y-Achse gebunden. Zum Beispiel platziertx0=50
den Punkt bei der 50er-Marke auf der x-Achse. - Papierkoordinaten (
xref: 'paper', yref: 'paper'
): Die Position ist relativ zum eigentlichen Plotbereich, wobei 0 der Anfang (linker/unterer Rand) und 1 das Ende (rechter/oberer Rand) ist. Dieses System ist unabhängig von den Datenwerten oder Achsenbereichen.
Das Problem: Du willst eine horizontale Linie über die gesamte Fläche auf y=10
ziehen. Wenn du ihn mit x0
und x1
unter Verwendung von Datenkoordinaten definierst, wird er nur den aktuellen Achsenbereich umfassen. Wenn du zoomen oder schwenken kannst, wird die Linie nicht bis zu den neuen Kanten verlängert.
Die Lösung: Damit sich eine Form über die gesamte Breite oder Höhe des Plotbereichs erstreckt, verwende die Koordinaten 'paper'
für die Achse, die du überspannen willst.
import plotly.graph_objects as go
fig = go.Figure(data=go.Scatter(x=[0, 10], y=[0, 20]))
# Incorrect: Vertical line that might not span the full height if the user zooms out.
# This line is drawn from y=0 to y=20 in DATA units.
fig.add_shape(
type="line",
x0=5, y0=0, x1=5, y1=20,
line=dict(color="Red", width=2, dash="dash"),
name="Incorrect Line" # Name for legend
)
# Correct: Vertical line that ALWAYS spans the full plot height.
# It is drawn from the bottom edge (0) to the top edge (1) of the PLOT area.
fig.add_shape(
type="line",
x0=8, y0=0, x1=8, y1=1,
yref="paper", # The key to spanning the full height
line=dict(color="Green", width=3),
name="Correct Line"
)
fig.update_layout(title_text="Correctly Spanning the Plot Area")
fig.show()
Ausgabe:
Überprüfe immer deine xref
und yref
Eigenschaften, um sicherzustellen, dass sich deine Formen bei der Benutzerinteraktion wie erwartet verhalten, z. B. beim Zoomen und Schwenken.
Überlegungen zur Leistung
Wenn du eine Handvoll Shapes zu einem Plot hinzufügst, sind die Auswirkungen auf die Leistung vernachlässigbar. Das Hinzufügen von Hunderten oder Tausenden von Formen kann jedoch das Rendering und die Interaktivität erheblich verlangsamen. Jede Form ist ein einzelnes SVG-Element (Scalable Vector Graphics), das dem DOM der Webseite hinzugefügt wird. Eine große Anzahl von DOM-Elementen wird den Browser belasten.
Hier sind Strategien zur Optimierung der Leistung:
- Schränke die Anzahl der Formen ein: Die einfachste Lösung. Wenn du Tausende von rechteckigen Flächen visualisieren musst, solltest du überlegen, ob ein anderer Diagrammtyp wie
go.Heatmap
die gleichen Informationen nicht effizienter als eine einzige Kurve anstelle von Tausenden von Formobjekten darstellen kann. - Verwende
update_layout
für große Zugaben: Wie bereits erwähnt, ist das Hinzufügen einer Liste von Formen überfig.update_layout(shapes=...)
performanter als der Aufruf vonfig.add_shape()
in einer Schleife. - Betrachte WebGL-Spuren für Daten: Während die Formen selbst als SVG gerendert werden, kannst du die Gesamtleistung eines komplexen Plots verbessern, indem du WebGL-basierte Spuren (z. B.
go.Scattergl
) für deine Hauptdaten verwendest. Dadurch wird das Rendering der Daten auf die GPU verlagert und die CPU kann die SVG-Formen reibungsloser verarbeiten. Dies ist nützlich, wenn du eine große Anzahl von Datenpunkten und eine überschaubare Anzahl von Formen hast.
Für die meisten Anwendungsfälle ist es wichtig, dass du die Anzahl der einzigartigen Formelemente, die du erstellst, im Auge behältst. Bevor du tausende von Plotly-Formen in einer Schleife hinzufügst, solltest du überlegen, ob es eine leistungsfähigere Visualisierungsstrategie gibt.
Fazit
Die Beherrschung von Plotly Shapes verwandelt deine Diagramme von einfachen Datendarstellungen in fesselnde, kontextreiche Geschichten. Wir haben uns das Zeichnen von einfachen Linien und Rechtecken bis hin zu komplexen, interaktiven Geometrien angesehen.
Wenn du diese Techniken anwendest, kannst du den Fokus deines Publikums lenken, wichtige Erkenntnisse hervorheben und intuitivere Visualisierungen erstellen, die klar und wirkungsvoll kommunizieren.
Bist du bereit, diese Fähigkeiten anzuwenden? Beginne noch heute mit der Erstellung leistungsfähigerer Visualisierungen, indem du die Einführung in die Datenvisualisierung mit Plotly in Python und stelle dein Wissen auf die Probe.
Plotly Shapes FAQs
Wofür werden die Plotly-Formen verwendet?
Plotly Shapes werden verwendet, um Anmerkungen wie Linien, Rechtecke und Kreise hinzuzufügen, um wichtige Datenbereiche in einem Diagramm hervorzuheben.
Wie fügst du in Plotly mehrere Formen hinzu?
Du kannst mehrere Formen effizient hinzufügen, indem du eine Liste von Form-Wörterbüchern an das shapes
Attribut in fig.update_layout()
.
Wie zeichnest du eine vertikale Linie in Plotly?
Du kannst eine vollständige vertikale Linie zeichnen, indem du type='line'
und die Eigenschaft yref='paper'
Eigenschaft so einstellst, dass sie die gesamte Plot-Höhe umfasst.
Kannst du in Plotly eine Form hinter die Daten setzen?
Ja, du kannst eine Form hinter Datenspuren platzieren, indem du ihre layer
Eigenschaft auf 'below'
.
Wie fügst du in Plotly eine Form zu nur einem Subplot hinzu?
Du kannst eine Form zu einem bestimmten Subplot hinzufügen, indem du die xref
und yref
Argumente in seiner Definition angibst.
Ich bin Data Science Content Writer. Ich liebe es, Inhalte rund um KI/ML/DS-Themen zu erstellen. Außerdem erforsche ich neue KI-Tools und schreibe über sie.