[PYTHON] Creating a graph using the plotly button and slider

Thing you want to do

--Create a button in the graph and press the button to operate the layout such as show / hide plot and title. --Make it possible to operate the displayed plot with a slider

button_slider_plotly.gif

environment

pip

python


pip install plotly
pip install numpy

Button review

button_plotly.gif

python


import numpy as np
import plotly.offline as offline
import plotly.graph_objs as go
import plotly

#Get line color
colors = plotly.colors.DEFAULT_PLOTLY_COLORS

x = np.linspace(-5, 5, 11)
data = []
for i in range(1, 4):
    trace = go.Scatter(
        x=x,
        y=x ** i,
        name="y{}".format(i),
        mode="lines",
        line=dict(color=colors[i], width=6),
        visible=False,
        showlegend=True
    )

    data.append(trace)
#Make the 0th of data visible as the initial state
data[0].visible = True

"""
Button creation location
Key description
active:Specify the button that is pressed in the initial state, and enter the list index of the buttons key value
type:Dropdown or button( "dropdown" | "buttons" ), default="dropdown"
buttons:Button settings
"""
buttons = []
for ii in range(len(data)):
    visible = [False] * len(data)  # len(data)=Because 3, visible=[False, False, False]
    visible[ii] = True  #Set only the iith to True, ex) [True, False, False]
    button = dict(label=data[ii].name,
                  method="update",  #To update the layout"update"
                  args=[dict(visible=visible),  #Only the trace of the part set to True can be seen
                        dict(title="button_plotly_{}".format(data[ii].name),  #title update
                             yaxis=dict(title="yaxis_{}".format(data[ii].name), showspikes=True))])  #y-axis label update
    buttons.append(button)

updatemenus = [dict(active=0, type="buttons", buttons=buttons)]

layout = go.Layout(
    title="button_plotly_y1",
    xaxis=dict(title="xaxis", showspikes=True, domain=[0.05, 1.0]),
    yaxis=dict(title="yaxis_y1", showspikes=True),
    font=dict(size=16),
    updatemenus=updatemenus,
    showlegend=True)

fig = dict(data=data, layout=layout)
offline.plot(fig, auto_open=True, include_plotlyjs="cdn", filename=r"./button_plotly.html")

Below is where the button is created. updatemenus = [dict (active = 0, type =" buttons "," buttons "= buttons)] "buttons" = buttons` creates information (show / hide, etc.) when the button is pressed. This is the place where you are.

buttons is a list, which contains a dictionary of layout information (button variables below).

python


"""
Button creation location
Key description
active:Specify the button that is pressed in the initial state, and enter the list index of the buttons key value
type:Dropdown or button( "dropdown" | "buttons" ), default="dropdown"
buttons:Button settings
"""
buttons = []
for ii in range(len(data)):
    visible = [False] * len(data)  # len(data)=Because 3, visible=[False, False, False]
    visible[ii] = True  #Set only the iith to True, ex) [True, False, False]
    button = dict(label=data[ii].name,
                  method="update",  #To update the layout"update"
                  args=[dict(visible=visible),  #Only the trace of the part set to True can be seen
                        dict(title="button_plotly_{}".format(data[ii].name),  #title update
                             yaxis=dict(title="yaxis_{}".format(data[ii].name), showspikes=True))])  #y-axis label update
    buttons.append(button)

updatemenus = [dict(active=0, type="buttons", buttons=buttons)]


This time, I wrote to show / hide the plot and switch the title and y-axis label with the button.

python


visible=[False] * len(data)
visble[ii] = True

Sets which plot to display.

For example, when data = [trace1, trace2, trace3] and visible = [True, False, False], only trace1 is displayed.

Finally, you can create a button on the graph with go.Layout (updatemenus = updatemenus).

Details Creating a graph with plotly button-Qiita

Review of the slider

slider_plotly.gif

python


import numpy as np
import plotly.offline as offline
import plotly.graph_objs as go

# sin,Save cos wave traces separately
sin_data, cos_data = [], []
x = np.linspace(0, 10, 101)

for step in np.linspace(0, 5, 51):
    y = np.sin(step * x)
    y2 = np.cos(step * x)

    sin_trace = go.Scatter(
        x=x,
        y=y,
        name="sin {:.1f}Hz".format(step),
        line=dict(color="red", width=3),
        visible=False, )

    cos_trace = go.Scatter(
        x=x,
        y=y2,
        name="cos {:.1f}Hz".format(step),
        line=dict(color="blue", width=3),
        visible=False, )

    sin_data.append(sin_trace)
    cos_data.append(cos_trace)

# sin,Both cos are index by default=Show 10 traces
sin_data[10].visible = True
cos_data[10].visible = True

data = sin_data + cos_data

steps = []
"""
sin_data, cos_Display of data/Set hidden separately, then combine and add to visible key
For example, when the slider is 2,
sin_visible = [False, False, True, False,...]
cos_visible = [False, False, True, False,...]
By combining the two after,cos both index=Allow 2 traces to be displayed
"""
for s in range(len(sin_data)):
    # sin_data, cos_Hide all data once
    sin_visible, cos_visible = [False] * len(sin_data), [False] * len(cos_data)
    #Make only the sth visible
    sin_visible[s], cos_visible[s] = True, True
    step = dict(method="update",
                args=[{"visible": sin_visible + cos_visible},
                      {"title": "Simple slider step: {}".format(s)}]
                )
    steps.append(step)

sliders = [dict(active=10, currentvalue=dict(prefix="Frequency: "), pad=dict(t=50), steps=steps)]

layout = go.Layout(
    title="Simple slider step: 10",
    xaxis=dict(title="x"),
    yaxis=dict(title="y"),
    font=dict(size=16),
    hovermode='x unified',
    hoverlabel=dict(font_size=16),
    sliders=sliders,
    showlegend=True)

fig = dict(data=data, layout=layout)

offline.plot(fig, include_plotlyjs="cdn", filename="plots.html")

I am creating a slider below

python


steps = []
"""
sin_data, cos_Display of data/Set hidden separately, then combine and add to visible key
For example, when the slider is 2,
sin_visible = [False, False, True, False,...]
cos_visible = [False, False, True, False,...]
By combining the two after,cos both index=Allow 2 traces to be displayed
"""
for s in range(len(sin_data)):
    # sin_data, cos_Hide all data once
    sin_visible, cos_visible = [False] * len(sin_data), [False] * len(cos_data)
    #Make only the sth visible
    sin_visible[s], cos_visible[s] = True, True
    step = dict(method="update",
                args=[{"visible": sin_visible + cos_visible},
                      {"title": "Simple slider step: {}".format(s)}]
                )
    steps.append(step)

sliders = [dict(active=10, currentvalue=dict(prefix="Frequency: "), pad=dict(t=50), steps=steps)]

What you are doing is not much different from a button. sliders = [dict (active = 10, currentvalue = dict (prefix =" Frequency: "), pad = dict (t = 50), steps = steps)] when steps = steps moves the slider This is where the information (show / hide, etc.) is created.

steps is a list, which contains a dictionary of layout information (step variables in the above).

Finally, go.Layout (sliders = sliders) will create a slider on the graph.

Details Application of graphs using plotly sliders --Qiita

Sample graph

button_slider_plotly.gif

With 3 buttons

--both sin and cos (ALL) --sin only (SIN) --cos only (COS)

After switching the display of, change the frequency with the slider for the visible plot.

Create three sliders, ALL, SIN, and COS, and replace the sliders when updating the layout with the button.

python


import copy
import numpy as np
import plotly.offline as offline
import plotly.graph_objs as go

# sin,Save cos wave traces separately
sin_data, cos_data = [], []
x = np.linspace(0, 10, 101)

for step in np.linspace(0, 5, 51):
    y = np.sin(step * x)
    y2 = np.cos(step * x)

    sin_trace = go.Scatter(
        x=x,
        y=y,
        name="sin {:.1f}Hz".format(step),
        line=dict(color="red", width=3),
        visible=False, )

    cos_trace = go.Scatter(
        x=x,
        y=y2,
        name="cos {:.1f}Hz".format(step),
        line=dict(color="blue", width=3),
        visible=False, )

    sin_data.append(sin_trace)
    cos_data.append(cos_trace)

sin_data[10].visible = True
cos_data[10].visible = True

data = sin_data + cos_data

steps = {"ALL": [], "SIN": [], "COS": []}
"""
There are a total of 4 lists of visible information
sin_visible_false:All visible sin waves are False
cos_visible_false:All visible cos waves are False
sin_visible_true:sine wave index=s visible is True
cos_visible_true:cos wave index=visible of s is True

If you don't want to display it, you can set it to False.
sin,visible information when displaying both cos: sin_visible_true + cos_visible_true
Visible information when displaying only sin: sin_visible_true + cos_visible_false
Visible information when displaying only cos: sin_visible_false + cos_visible_true
"""
for s in range(len(sin_data)):
    # sin_data, cos_Hide all data once
    sin_visible_false, cos_visible_false = [False] * len(sin_data), [False] * len(cos_data)
    # sin_visible_false, cos_visible_False copy creation, copy index=True for s
    sin_visible_true, cos_visible_true = copy.copy(sin_visible_false), copy.copy(cos_visible_false)
    sin_visible_true[s], cos_visible_true[s] = True, True

    step_all = dict(method="update",
                    args=[{"visible": sin_visible_true + cos_visible_true},
                          {"title": "slider_button_ALL step: {}".format(s)}]
                    )
    step_sin = dict(method="update",
                    args=[{"visible": sin_visible_true + cos_visible_false},
                          {"title": "slider_button_SIN step: {}".format(s)}]
                    )
    
    step_cos = dict(method="update",
                    args=[{"visible": sin_visible_false + cos_visible_true},
                          {"title": "slider_button_COS step: {}".format(s)}]
                    )

    steps["ALL"].append(step_all)
    steps["SIN"].append(step_sin)
    steps["COS"].append(step_cos)

sliders = {}
for key, step in steps.items():
    slider = [dict(active=10, currentvalue=dict(prefix="Frequency: "), pad=dict(t=50), steps=step)]
    sliders[key] = slider

buttons = []
for key, slider in sliders.items():
    slider_active = slider[0]["active"]
    slider_visible = slider[0]["steps"][slider_active]["args"][0]["visible"]
    button = dict(label=key,
                  method="update",
                  args=[dict(visible=slider_visible),
                        dict(title="slider_button_{} step: {}".format(key, slider_active),
                             yaxis=dict(title="y {}".format(key)),
                             sliders=slider)])
    buttons.append(button)

updatemenus = [dict(active=0, type="buttons", buttons=buttons)]

layout = go.Layout(
    title="slider_button_ALL step: 10",
    xaxis=dict(title="x", domain=[0.05, 1]),
    yaxis=dict(title="y ALL"),
    font=dict(size=16),
    hovermode='x unified',
    hoverlabel=dict(font_size=16),
    sliders=sliders["ALL"],
    updatemenus=updatemenus,
    showlegend=True)

fig = dict(data=data, layout=layout)

offline.plot(fig, auto_open=True, include_plotlyjs="cdn", filename=r"./slider_button_plotly.html",
             config={'modeBarButtonsToAdd': ['drawline', 'drawopenpath', 'drawclosedpath', 'drawcircle', 'drawrect',
                                             'eraseshape']})

I am creating a plot display when the slider is moved.

python


steps = {"ALL": [], "SIN": [], "COS": []}
"""
There are a total of 4 lists of visible information
sin_visible_false:All visible sin waves are False
cos_visible_false:All visible cos waves are False
sin_visible_true:sine wave index=visible of s is True
cos_visible_true:cos wave index=visible of s is True

If you don't want to display it, you can set it to False.
sin,visible information when displaying both cos: sin_visible_true + cos_visible_true
Visible information when displaying only sin: sin_visible_true + cos_visible_false
Visible information when displaying only cos: sin_visible_false + cos_visible_true
"""
for s in range(len(sin_data)):
    # sin_data, cos_Hide all data once
    sin_visible_false, cos_visible_false = [False] * len(sin_data), [False] * len(cos_data)
    # sin_visible_false, cos_visible_False copy creation, copy index=True for s
    sin_visible_true, cos_visible_true = copy.copy(sin_visible_false), copy.copy(cos_visible_false)
    sin_visible_true[s], cos_visible_true[s] = True, True

    step_all = dict(method="update",
                    args=[{"visible": sin_visible_true + cos_visible_true},
                          {"title": "slider_button_ALL step: {}".format(s)}]
                    )
    step_sin = dict(method="update",
                    args=[{"visible": sin_visible_true + cos_visible_false},
                          {"title": "slider_button_SIN step: {}".format(s)}]
                    )

    step_cos = dict(method="update",
                    args=[{"visible": sin_visible_false + cos_visible_true},
                          {"title": "slider_button_COS step: {}".format(s)}]
                    )

    steps["ALL"].append(step_all)
    steps["SIN"].append(step_sin)
    steps["COS"].append(step_cos)

sliders = {}
for key, step in steps.items():
    slider = [dict(active=10, currentvalue=dict(prefix="Frequency: "), pad=dict(t=50), steps=step)]
    sliders[key] = slider

The contents of sliders are {" ALL ": slider when ALL," SIN ": slider when SIN, ...}

python


buttons = []
for key, slider in sliders.items():
    slider_active = slider[0]["active"]
    slider_visible = slider[0]["steps"][slider_active]["args"][0]["visible"]
    button = dict(label=key,
                  method="update",
                  args=[dict(visible=slider_visible),
                        dict(title="slider_button_{} step: {}".format(key, slider_active),
                             yaxis=dict(title="y {}".format(key)),
                             sliders=slider)])
    buttons.append(button)

updatemenus = [dict(active=0, type="buttons", buttons=buttons)]

I am creating a button. slider_visible = slider [0] ["steps "] [slider_active] ["args"] [0] ["visible"] gets the visible information of the initial position of the slider.

In the case of the above script, the initial position of the slider is set to 10, so the position of the slider and the display will not match unless the display immediately after switching the button also matches it.

python


layout = go.Layout(
    title="slider_button_ALL step: 10",
    xaxis=dict(title="x", domain=[0.05, 1]),
    yaxis=dict(title="y ALL"),
    font=dict(size=16),
    hovermode='x unified',
    hoverlabel=dict(font_size=16),
    sliders=sliders["ALL"],
    updatemenus=updatemenus,
    showlegend=True)

fig = dict(data=data, layout=layout)

offline.plot(fig, auto_open=True, include_plotlyjs="cdn", filename=r"./slider_button_plotly.html",
             config={'modeBarButtonsToAdd': ['drawline', 'drawopenpath', 'drawclosedpath', 'drawcircle', 'drawrect',
                                             'eraseshape']})

The layout is decided and output. The default is to display ALL.

config = {...} adds a drawing button on the upper right.

reference

official Custom Buttons | Python | Plotly layout.updatemenus | Python | Plotly Plotly Python Graphing Library | Python | Plotly

Recommended Posts

Creating a graph using the plotly button and slider
Create a graph using the Sympy module
Create graph with plotly button
A memo when creating a directed graph using Graphviz in Python
The story of creating a database using the Google Analytics API
Creating a web application using Flask ②
Creating a simple table using prettytable
Creating a web application using Flask ①
Creating a learning model using MNIST
Creating a web application using Flask ③
Make a nice graph with plotly
Creating a web application using Flask ④
How to divide and process a data frame using the groupby function
Calculate the shortest route of a graph with Dijkstra's algorithm and Python
Reading and creating a mark sheet using Python OpenCV (Tips for reading well)
How to draw a graph using Matplotlib
Behind the graph drawing algorithm and Networkx
Creating a data analysis application using Streamlit
Add a layer using the Keras backend
I got the date from the pub rice in Kagawa and drew a graph
Create a REST API using the model learned in Lobe and TensorFlow Serving.
Use libsixel to output Sixel in Python and output a Matplotlib graph to the terminal.
[Python] A program that finds the minimum and maximum values without using methods
Creating a position estimation model for the Werewolf Intelligence Tournament using machine learning
Get the stock price of a Japanese company with Python and make a graph
Solve the knapsack problem using pyomo and glpk
A memo that made a graph animated with plotly
ffmpeg-Build a python environment and split the video
Write a TCP server using the SocketServer module
Creating an interactive application using a topic model
Create a web map using Python and GDAL
Checking methods and variables using the library see
Response the resized image using Flask and PILImage
Generate a hash value using the HMAC method.
Create a Mac app using py2app and Python3! !!
"Creating a stock price dataset" and "Implementing AR (1)"
[Bash] Creating a safe and versatile temp directory
A discussion of the strengths and weaknesses of Python
Create a GUI on the terminal using curses
I tried to notify the update of "Become a novelist" using "IFTTT" and "Become a novelist API"