diff --git a/doc/python/legend.md b/doc/python/legend.md index 20021699be..0ed08929d0 100644 --- a/doc/python/legend.md +++ b/doc/python/legend.md @@ -6,7 +6,7 @@ jupyter: extension: .md format_name: markdown format_version: '1.3' - jupytext_version: 1.17.2 + jupytext_version: 1.19.1 kernelspec: display_name: Python 3 (ipykernel) language: python @@ -20,7 +20,7 @@ jupyter: name: python nbconvert_exporter: python pygments_lexer: ipython3 - version: 3.9.0 + version: 3.14.3 plotly: description: How to configure and style the legend in Plotly with Python. display_as: file_settings @@ -832,6 +832,63 @@ fig.show() ``` +### Legend Title Click Behavior + +*New in 6.6* + +When a figure has multiple legends: + +- Single-clicking a legend title toggles the visibility of all items in that legend +- Double-clicking a legend title toggles the visibility of all items in other legends + +This default behavior can be changed for a legend by setting `titleclick` and `titledoubleclick`, which accept: +- `"toggle"`: toggles the visibility of items in the clicked legend +- `"toggleothers"`: toggles the visibility of items in other legends +- `False`: disables click behavior + +For example, to swap the behaviors: + +```python +import plotly.graph_objects as go + +fig = go.Figure( + data=[ + go.Scatter(x=[1, 2, 3], y=[1, 2, 3], name="Trace 1"), + go.Scatter(x=[1, 2, 3], y=[2, 3, 4], name="Trace 2"), + go.Scatter(x=[1, 2, 3], y=[3, 4, 5], name="Trace 3", legend="legend2"), + go.Scatter(x=[1, 2, 3], y=[4, 5, 6], name="Trace 4", legend="legend2"), + ], + layout=dict( + legend=dict( + title=dict(text="First Legend"), + titleclick="toggleothers", + titledoubleclick="toggle", + ), + legend2=dict( + title=dict(text="Second Legend"), + titleclick="toggleothers", + titledoubleclick="toggle", + y=0.5, + ), + ), +) + +fig.show() +``` + + +To disable title click behavior, set `titleclick` and `titledoubleclick` to `False`: + +```python +fig.update_layout( + legend=dict(titleclick=False, titledoubleclick=False), + legend2=dict(titleclick=False, titledoubleclick=False), +) +``` + +> **Note:** Legend title click interactions are not supported for legends containing pie or pie-like traces. + + #### Reference See https://plotly.com/python/reference/layout/#layout-legend for more information! diff --git a/doc/python/marker-style.md b/doc/python/marker-style.md index a7bd085e7b..27b2c1efc5 100644 --- a/doc/python/marker-style.md +++ b/doc/python/marker-style.md @@ -6,7 +6,7 @@ jupyter: extension: .md format_name: markdown format_version: '1.3' - jupytext_version: 1.14.6 + jupytext_version: 1.19.1 kernelspec: display_name: Python 3 (ipykernel) language: python @@ -20,7 +20,7 @@ jupyter: name: python nbconvert_exporter: python pygments_lexer: ipython3 - version: 3.10.11 + version: 3.14.3 plotly: description: How to style markers in Python with Plotly. display_as: file_settings @@ -107,6 +107,49 @@ fig.show() Fully opaque, the default setting, is useful for non-overlapping markers. When many points overlap it can be hard to observe density. +### Dashed Marker Borders + +*New in 6.6* + +Set `dash` on `marker.line` to control the dash pattern of marker borders. Supported values are: `'solid'` (default), `'dot'`, `'dash'`, `'longdash'`, `'dashdot'`, `'longdashdot'`, or a custom dash length list in px (for example, `'12px,6px'`). + +```python +import plotly.graph_objects as go + +fig = go.Figure(go.Scatter( + x=[1, 2, 3, 4, 5], + y=[2, 4, 3, 5, 4], + mode="markers", + marker=dict( + size=25, + color="white", + line=dict(width=2, color="blue", dash="dot") + ) +)) + +fig.show() +``` + +You can also pass an array of dash styles to set different styles per marker: + +```python +import plotly.graph_objects as go + +styles = ["solid", "dot", "dash", "longdash", "dashdot", "longdashdot"] + +fig = go.Figure(go.Scatter( + x=list(range(len(styles))), + y=[0] * len(styles), + mode="markers+text", + text=styles, + textposition="bottom center", + marker=dict(size=30, color="white", line=dict(color="blue", width=2, dash=styles)) +)) + +fig.show() +``` + +The `marker.line.dash` attribute is available on `go.Scatter`, `go.Scatterpolar`, `go.Scattergeo`, `go.Scatterternary`, `go.Scattercarpet`, and `go.Scattersmith` traces. ### Control Marker Border with Dash diff --git a/doc/python/shapes.md b/doc/python/shapes.md index 6348002632..c0e6809844 100644 --- a/doc/python/shapes.md +++ b/doc/python/shapes.md @@ -6,7 +6,7 @@ jupyter: extension: .md format_name: markdown format_version: '1.3' - jupytext_version: 1.16.3 + jupytext_version: 1.19.1 kernelspec: display_name: Python 3 (ipykernel) language: python @@ -20,7 +20,7 @@ jupyter: name: python nbconvert_exporter: python pygments_lexer: ipython3 - version: 3.10.14 + version: 3.14.3 plotly: description: How to make SVG shapes in python. Examples of lines, circle, rectangle, and path. @@ -488,6 +488,65 @@ fig.update_layout( fig.show() ``` +#### Shapes Spanning Subplots + +*New in 6.6* + +You can create shapes that span multiple subplots by passing an array of axis references to `xref` and `yref`. Each element in the array specifies which axis the corresponding coordinate refers to. For example, in the following code, with `xref=["x", "x2"]`, `x0` refers to the `x` axis and `x1` refers to the `x2` axis. + +```python +import plotly.graph_objects as go +from plotly.subplots import make_subplots + +fig = make_subplots(rows=1, cols=2) + +fig.add_trace(go.Scatter(x=[1, 2, 3], y=[4, 5, 6], mode="markers", marker=dict(size=10)), row=1, col=1) +fig.add_trace(go.Scatter(x=[1, 2, 3], y=[6, 5, 4], mode="markers", marker=dict(size=10)), row=1, col=2) + +fig.add_shape( + type="rect", + xref=["x", "x2"], # x0 uses the x-axis from subplot 1 ("x"), while x1 uses the x-axis from subplot 2 ("x2") + yref=["y", "y2"], # y0 uses the y-axis from subplot 1 ("y"), while y1 uses the y-axis from subplot 2 ("y2") + x0=2, y0=4.5, + x1=3, y1=5.5, + fillcolor="rgba(255, 0, 0, 0.2)", + line=dict(color="red", width=2), +) + +fig.show() +``` + +For `path` shapes, the array must have one entry for each coordinate in the path string. Each coordinate in the path maps to the corresponding element in the `xref`/`yref` array, in order. + +```python +import plotly.graph_objects as go +from plotly.subplots import make_subplots + +fig = make_subplots(rows=1, cols=2) + +fig.add_trace(go.Scatter(x=[1, 2, 3], y=[1, 2, 3], mode="markers"), row=1, col=1) +fig.add_trace(go.Scatter(x=[1, 2, 3], y=[3, 2, 1], mode="markers"), row=1, col=2) + +# Chevron shape spanning both subplots +# Path coordinates map to axis refs in order: +# M 2.5 1.5 -> xref[0]=x, yref[0]=y (start in subplot 1) +# L 1.5 2 -> xref[1]=x2, yref[1]=y2 (tip in subplot 2) +# L 2.5 2.5 -> xref[2]=x, yref[2]=y (end in subplot 1) + +fig.add_shape( + type="path", + path="M 2.5 1.5 L 1.5 2 L 2.5 2.5", + xref=["x", "x2", "x"], + yref=["y", "y2", "y"], + line=dict(color="purple", width=3), +) + +fig.show() +``` + +**Note:** When using arrays with `xref` and `yref`, `xsizemode="pixel"` and `ysizemode="pixel"` are not supported. + + #### Adding the Same Shapes to Multiple Subplots The same shape can be added to multiple facets by using the `'all'` keyword in the `row` and `col` arguments. For example