diff --git a/doc/python/2D-Histogram.md b/doc/python/2D-Histogram.md index 289beb5d09..d272ca54af 100644 --- a/doc/python/2D-Histogram.md +++ b/doc/python/2D-Histogram.md @@ -61,7 +61,7 @@ fig = px.density_heatmap(df, x="total_bill", y="tip", nbinsx=20, nbinsy=20, colo fig.show() ``` -Marginal plots can be added to visualize the 1-dimensional distributions of the two variables. Here we use a marginal [`histogram`](/python/histograms/). Other allowable values are `violin`, `box` and `rug`. +Marginal plots can be added to visualize the 1-dimensional distributions of the two variables. Here we use a marginal [`histogram`](/python/histograms/). Other allowable values are `violin`, `box`, `rug`, and `heatmap`. ```python import plotly.express as px @@ -71,6 +71,18 @@ fig = px.density_heatmap(df, x="total_bill", y="tip", marginal_x="histogram", ma fig.show() ``` +*New in 7.1* + +`marginal_x="heatmap"` and `marginal_y="heatmap"` draw the margin as a single-row or single-column heatmap strip. Each strip uses the same aggregate and the same color scale as the main plot. See [Marginal Plots](/python/marginal-plots/) for more detail. + +```python +import plotly.express as px +df = px.data.tips() + +fig = px.density_heatmap(df, x="total_bill", y="tip", marginal_x="heatmap", marginal_y="heatmap") +fig.show() +``` + Density heatmaps can also be [faceted](/python/facet-plots/): ```python diff --git a/doc/python/configuration-options.md b/doc/python/configuration-options.md index 92986aa636..2c74630c6e 100644 --- a/doc/python/configuration-options.md +++ b/doc/python/configuration-options.md @@ -202,6 +202,34 @@ fig = px.bar(x=[1, 2, 3], y=[1, 3, 1]) fig.show(config=config) ``` +### Adding a "Download Plot as JSON" Button + +*New in 7.1* + +The modebar can include a button that downloads the figure as a JSON file. The file holds the full figure, which is every attribute with its default filled in, together with the figure's frames, its configuration, and the Plotly.js version. It is not the compact figure you wrote in Python. + +The button is optional, so add it with the `modeBarButtonsToAdd` configuration key: + +```python +import plotly.express as px + +fig = px.bar(x=[1, 2, 3], y=[1, 3, 1]) + +fig.show(config={'modeBarButtonsToAdd': ['downloadJson']}) +``` + +The `layout.modebar.add` attribute adds the same button, and applies to the figure itself rather than to one call to `show()`: + +```python +import plotly.express as px + +fig = px.bar(x=[1, 2, 3], y=[1, 3, 1]) + +fig.update_layout(modebar_add=['downloadJson']) + +fig.show() +``` + ### Removing Modebar Buttons To delete buttons from the modebar, pass an array of strings containing the names of the buttons you want to remove to the `modeBarButtonsToRemove` attribute in the figure's configuration dictionary. Note that different chart types have different default modebars. The following is a list of all the modebar buttons and the chart types they are associated with: @@ -214,10 +242,12 @@ To delete buttons from the modebar, pass an array of strings containing the name - **Geo**: `zoomInGeo`, `zoomOutGeo`, `resetGeo`, `hoverClosestGeo` - **Tile maps**: `zoomInMap`, `zoomOutMap`, `resetViewMap` - **Sankey**: `resetSankeyGroup` - - **Other**: `hoverClosestPie`, `toggleHover`, `resetViews`, `toImage`, `sendChartToCloud`, `toggleSpikelines` + - **Other**: `hoverClosestPie`, `toggleHover`, `resetViews`, `toImage`, `downloadJson`, `sendChartToCloud`, `toggleSpikelines` *Changed in 7.0*: `handleDrag3d` and `hoverClosestGl2d` no longer exist, and `sendDataToCloud` is now named `sendChartToCloud`. +*New in 7.1*: `downloadJson`. The modebar shows this button only when you add it. + ```python import plotly.graph_objects as go @@ -308,7 +338,10 @@ fig.show() ``` ### Double-Click Delay -Sets the maximum delay between two consecutive clicks to be interpreted as a double-click in milliseconds. This is the time interval between first mousedown and second mouseup. The default timing is 300 ms (less than half a second). + +*Changed in 7.1* + +Sets the maximum delay between two consecutive clicks to be interpreted as a double-click in milliseconds. This is the time interval between first mousedown and second mouseup. The default timing is 500 ms (half a second). Earlier versions used 300 ms. This setting propagates to all on-subplot double clicks (except for `geo` and `map`). ```python diff --git a/doc/python/legend.md b/doc/python/legend.md index 6e883934f1..d75ce2f5d2 100644 --- a/doc/python/legend.md +++ b/doc/python/legend.md @@ -697,6 +697,41 @@ fig.show() ``` +#### Group double-click toggle behavior + +*New in 7.1* + +`groupdoubleclick` sets the scope of a double-click on a legend item, the way `groupclick` sets the scope of a single click. A double-click isolates, because `itemdoubleclick` defaults to `"toggleothers"`. Set `groupdoubleclick` to `"togglegroup"`, and a double-click hides every item outside the group of the item clicked on. A second double-click brings those items back. Set it to `"toggleitem"`, and a double-click isolates the single item clicked on. + +In the example below, a single click hides one item, and a double-click leaves only the group of the item clicked on. + +```python +import plotly.graph_objects as go + +fig = go.Figure() + +for name, color, y in [("first legend group", "Crimson", [2, 1, 3]), + ("first legend group - average", "Crimson", [2, 2, 2])]: + fig.add_trace(go.Scatter(x=[1, 2, 3], y=y, legendgroup="group", + legendgrouptitle_text="First Group Title", + name=name, mode="lines+markers", + line=dict(color=color))) + +for name, color, y in [("second legend group", "MediumPurple", [4, 9, 2]), + ("second legend group - average", "MediumPurple", [5, 5, 5])]: + fig.add_trace(go.Scatter(x=[1, 2, 3], y=y, legendgroup="group2", + legendgrouptitle_text="Second Group Title", + name=name, mode="lines+markers", + line=dict(color=color))) + +fig.update_layout(title=dict(text="Try Clicking and Double-Clicking on the Legend Items!"), + legend=dict(groupclick="toggleitem", groupdoubleclick="togglegroup")) + +fig.show() +``` + +`groupdoubleclick` takes the value of `groupclick` when you do not set it. To make a double-click toggle a group rather than isolate it, set `itemdoubleclick` to `"toggle"` as well. + ### Legend items for continuous fields (2D and 3D) Traces corresponding to 2D fields (e.g. `go.Heatmap`, `go.Histogram2d`) or 3D fields (e.g. `go.Isosurface`, `go.Volume`, `go.Cone`) can also appear in the legend. They come with legend icons corresponding to each trace type, which are colored using the same colorscale as the trace. diff --git a/doc/python/marginal-plots.md b/doc/python/marginal-plots.md index bd1ff69e74..880e56eb06 100644 --- a/doc/python/marginal-plots.md +++ b/doc/python/marginal-plots.md @@ -61,6 +61,8 @@ fig.show() ### Marginal Heatmaps on Density Heatmaps +*New in 7.1* + `marginal_x` and `marginal_y` also accept `"heatmap"` for [`density_heatmap`](/python/2D-Histogram/). This draws a single-row or single-column heatmap strip, colored by the same aggregate (`histfunc` of `z`, or count by default) as the main plot, and sharing its color scale. This is not supported for `density_contour`, since a contour plot's colorbar is discrete and not compatible with the continuous colorbar used by the marginal heatmap. ```python diff --git a/doc/python/supported-colors.md b/doc/python/supported-colors.md index c558eb2b1c..eb362c8bbb 100644 --- a/doc/python/supported-colors.md +++ b/doc/python/supported-colors.md @@ -157,3 +157,20 @@ Version 7 parses these strings according to that specification. Four formats tha | Hexadecimal values without a leading `#` | `"fff"` | `"#fff"` | These rules apply to color strings only. Numeric arrays used with a [colorscale](/python/colorscales/) are unaffected. + +### Converting a Hexadecimal Color to RGB + +*Changed in 7.1* + +`plotly.colors.hex_to_rgb` converts a hexadecimal color string to a tuple of red, green, and blue values. It takes 3 or 6 hexadecimal digits, with or without a leading `#`: + +```python +import plotly.colors as colors + +print(colors.hex_to_rgb("#EF553B")) +print(colors.hex_to_rgb("#FFF")) +``` + +A 4-digit or 8-digit string carries an alpha channel, which a tuple of red, green, and blue values cannot hold. `hex_to_rgb` drops the alpha channel, warns, and returns the 3 remaining values. Earlier versions returned 4 values instead of 3. + +Any other length raises a `ValueError`, which version 7.1 added. Earlier versions returned a tuple of the wrong length. `hex_to_rgb("#FFFF0")` returned 5 values, one for each digit. diff --git a/doc/python/tile-map-layers.md b/doc/python/tile-map-layers.md index 9aae04bf41..967062c8c1 100644 --- a/doc/python/tile-map-layers.md +++ b/doc/python/tile-map-layers.md @@ -56,6 +56,10 @@ Tile-based traces in Plotly use MapLibre. MapLibre-based traces (new in 5.24) are ones generated in Plotly Express using `px.scatter_map`, `px.line_map`, `px.choropleth_map`, `px.density_map`, or Graph Objects using `go.Scattermap`, `go.Choroplethmap`, or `go.Densitymap`. +*Changed in 7.1* + +Version 7.1 updates MapLibre GL JS from version 5 to version 6. Version 6 requires WebGL2, which raises the browser requirement for tile maps to Safari 15, Chrome 56, and Firefox 51. Outline-based maps and all other trace types are unaffected. + ### MapLibre