--- jupyter: jupytext: notebook_metadata_filter: all text_representation: extension: .md format_name: markdown format_version: '1.2' jupytext_version: 1.3.2 kernelspec: display_name: Python 3 language: python name: python3 language_info: codemirror_mode: name: ipython version: 3 file_extension: .py mimetype: text/x-python name: python nbconvert_exporter: python pygments_lexer: ipython3 version: 3.7.3 plotly: description: How to add custom buttons to update Plotly chart attributes in Python. display_as: controls language: python layout: base name: Custom Buttons order: 1 page_type: example_index permalink: python/custom-buttons/ thumbnail: thumbnail/custom-buttons.jpg --- #### Methods The [updatemenu method](https://plot.ly/python/reference/layout/updatemenus/#layout-updatemenus-items-updatemenu-buttons-items-button-method) determines which [plotly.js function](https://plot.ly/javascript/plotlyjs-function-reference/) will be used to modify the chart. There are 4 possible methods: - `"restyle"`: modify **data** or data attributes - `"relayout"`: modify **layout** attributes - `"update"`: modify **data and layout** attributes; combination of `"restyle"` and `"relayout"` - `"animate"`: start or pause an [animation](https://plot.ly/python/#animations)) #### Restyle Button The `"restyle"` method should be used when modifying the data and data attributes of the graph.<br> **Update One Data Attribute**<br> This example demonstrates how to update a single data attribute: chart `type` with the `"restyle"` method. ```python import plotly.graph_objects as go import pandas as pd # load dataset df = pd.read_csv("https://raw.githubusercontent.com/plotly/datasets/master/volcano.csv") # create figure fig = go.Figure() # Add surface trace fig.add_trace(go.Surface(z=df.values.tolist(), colorscale="Viridis")) # Update plot sizing fig.update_layout( width=800, height=900, autosize=False, margin=dict(t=0, b=0, l=0, r=0), template="plotly_white", ) # Update 3D scene options fig.update_scenes( aspectratio=dict(x=1, y=1, z=0.7), aspectmode="manual" ) # Add dropdown fig.update_layout( updatemenus=[ dict( type = "buttons", direction = "left", buttons=list([ dict( args=["type", "surface"], label="3D Surface", method="restyle" ), dict( args=["type", "heatmap"], label="Heatmap", method="restyle" ) ]), pad={"r": 10, "t": 10}, showactive=True, x=0.11, xanchor="left", y=1.1, yanchor="top" ), ] ) # Add annotation fig.update_layout( annotations=[ dict(text="Trace type:", showarrow=False, x=0, y=1.08, yref="paper", align="left") ] ) fig.show() ``` **Update Several Data Attributes**<br> This example demonstrates how to update several data attributes: colorscale, colorscale direction, and line display with the "restyle" method. This example uses the cmocean python package. You can install this package with `pip install cmocean`. ```python import plotly.graph_objects as go import pandas as pd # load dataset df = pd.read_csv("https://raw.githubusercontent.com/plotly/datasets/master/volcano.csv") # Create figure fig = go.Figure() # Add surface trace fig.add_trace(go.Heatmap(z=df.values.tolist(), colorscale="Viridis")) # Update plot sizing fig.update_layout( width=800, height=900, autosize=False, margin=dict(t=100, b=0, l=0, r=0), ) # Update 3D scene options fig.update_scenes( aspectratio=dict(x=1, y=1, z=0.7), aspectmode="manual" ) # Add drowdowns # button_layer_1_height = 1.08 button_layer_1_height = 1.12 button_layer_2_height = 1.065 fig.update_layout( updatemenus=[ dict( buttons=list([ dict( args=["colorscale", "Viridis"], label="Viridis", method="restyle" ), dict( args=["colorscale", "Cividis"], label="Cividis", method="restyle" ), dict( args=["colorscale", "Blues"], label="Blues", method="restyle" ), dict( args=["colorscale", "Greens"], label="Greens", method="restyle" ), ]), type = "buttons", direction="right", pad={"r": 10, "t": 10}, showactive=True, x=0.1, xanchor="left", y=button_layer_1_height, yanchor="top" ), dict( buttons=list([ dict( args=["reversescale", False], label="False", method="restyle" ), dict( args=["reversescale", True], label="True", method="restyle" ) ]), type = "buttons", direction="right", pad={"r": 10, "t": 10}, showactive=True, x=0.13, xanchor="left", y=button_layer_2_height, yanchor="top" ), dict( buttons=list([ dict( args=[{"contours.showlines": False, "type": "contour"}], label="Hide lines", method="restyle" ), dict( args=[{"contours.showlines": True, "type": "contour"}], label="Show lines", method="restyle" ), ]), type = "buttons", direction="right", pad={"r": 10, "t": 10}, showactive=True, x=0.5, xanchor="left", y=button_layer_2_height, yanchor="top" ), ] ) fig.update_layout( annotations=[ dict(text="colorscale", x=0, xref="paper", y=1.1, yref="paper", align="left", showarrow=False), dict(text="Reverse<br>Colorscale", x=0, xref="paper", y=1.06, yref="paper", showarrow=False), dict(text="Lines", x=0.47, xref="paper", y=1.045, yref="paper", showarrow=False) ]) fig.show() ``` #### Relayout Button The `"relayout"` method should be used when modifying the layout attributes of the graph.<br> **Update One Layout Attribute**<br> This example demonstrates how to update a layout attribute: chart `type` with the `"relayout"` method. ```python import plotly.graph_objects as go # Generate dataset import numpy as np np.random.seed(1) x0 = np.random.normal(2, 0.4, 400) y0 = np.random.normal(2, 0.4, 400) x1 = np.random.normal(3, 0.6, 600) y1 = np.random.normal(6, 0.4, 400) x2 = np.random.normal(4, 0.2, 200) y2 = np.random.normal(4, 0.4, 200) # Create figure fig = go.Figure() # Add traces fig.add_trace( go.Scatter( x=x0, y=y0, mode="markers", marker=dict(color="DarkOrange") ) ) fig.add_trace( go.Scatter( x=x1, y=y1, mode="markers", marker=dict(color="Crimson") ) ) fig.add_trace( go.Scatter( x=x2, y=y2, mode="markers", marker=dict(color="RebeccaPurple") ) ) # Add buttons that add shapes cluster0 = [dict(type="circle", xref="x", yref="y", x0=min(x0), y0=min(y0), x1=max(x0), y1=max(y0), line=dict(color="DarkOrange"))] cluster1 = [dict(type="circle", xref="x", yref="y", x0=min(x1), y0=min(y1), x1=max(x1), y1=max(y1), line=dict(color="Crimson"))] cluster2 = [dict(type="circle", xref="x", yref="y", x0=min(x2), y0=min(y2), x1=max(x2), y1=max(y2), line=dict(color="RebeccaPurple"))] fig.update_layout( updatemenus=[ dict( type="buttons", buttons=[ dict(label="None", method="relayout", args=["shapes", []]), dict(label="Cluster 0", method="relayout", args=["shapes", cluster0]), dict(label="Cluster 1", method="relayout", args=["shapes", cluster1]), dict(label="Cluster 2", method="relayout", args=["shapes", cluster2]), dict(label="All", method="relayout", args=["shapes", cluster0 + cluster1 + cluster2]) ], ) ] ) # Update remaining layout properties fig.update_layout( title_text="Highlight Clusters", showlegend=False, ) fig.show() ``` #### Update Button The `"update"` method should be used when modifying the data and layout sections of the graph.<br> This example demonstrates how to update which traces are displayed while simultaneously updating layout attributes such as the chart title and annotations. ```python import plotly.graph_objects as go import pandas as pd # Load dataset df = pd.read_csv( "https://raw.githubusercontent.com/plotly/datasets/master/finance-charts-apple.csv") df.columns = [col.replace("AAPL.", "") for col in df.columns] # Initialize figure fig = go.Figure() # Add Traces fig.add_trace( go.Scatter(x=list(df.index), y=list(df.High), name="High", line=dict(color="MediumSlateBlue"))) fig.add_trace( go.Scatter(x=list(df.index), y=[df.High.mean()] * len(df.index), name="High Average", visible=False, line=dict(color="MediumSlateBlue", dash="dash"))) fig.add_trace( go.Scatter(x=list(df.index), y=list(df.Low), name="Low", line=dict(color="DarkOrange"))) fig.add_trace( go.Scatter(x=list(df.index), y=[df.Low.mean()] * len(df.index), name="Low Average", visible=False, line=dict(color="DarkOrange", dash="dash"))) # Add Annotations and Buttons high_annotations = [dict(x=-0.05, y=df.High.mean(), xanchor="right", yanchor="bottom", xref="x domain", yref="y", text="High Avg:<br> %.2f" % df.High.mean(), showarrow=False), dict(x=df.High.idxmax(), y=df.High.max(), xref="x", yref="y", text="High Max:<br> %.2f" % df.High.max(), ax=0, ay=-40)] low_annotations = [dict(x=-0.05, y=df.Low.mean(), xanchor="right", yanchor="top", xref="x domain", yref="y", text="Low Avg:<br> %.2f" % df.Low.mean(), showarrow=False), dict(x=df.Low.idxmin(), y=df.Low.min(), xref="x", yref="y", text="Low Min:<br> %.2f" % df.Low.min(), ax=0, ay=40)] fig.update_layout( updatemenus=[ dict( type="buttons", direction="right", active=0, x=0.57, y=1.2, buttons=list([ dict(label="None", method="update", args=[{"visible": [True, False, True, False]}, {"title": "Yahoo", "annotations": []}]), dict(label="High", method="update", args=[{"visible": [True, True, False, False]}, {"title": "Yahoo High", "annotations": high_annotations}]), dict(label="Low", method="update", args=[{"visible": [False, False, True, True]}, {"title": "Yahoo Low", "annotations": low_annotations}]), dict(label="Both", method="update", args=[{"visible": [True, True, True, True]}, {"title": "Yahoo", "annotations": high_annotations + low_annotations}]), ]), ) ]) # Set title fig.update_layout( title_text="Yahoo", xaxis_domain=[0.05, 1.0] ) fig.show() ``` #### Animate Button Refer to our animation docs: https://plotly.com/python/#animations for examples on how to use the `animate` method with Plotly buttons. #### Reference See https://plotly.com/python/reference/layout/updatemenus/ for more information about `updatemenu` buttons.