[PYTHON] Application of graphs with plotly sliders

Introduction

This is a memo because I often create graphs with sliders with plotly.

Since the code is officially used to move one plot with the slider, I will describe a little application such as when you want to move multiple plots at the same time.

Official site (slider explanation page) Sliders | Python | Plotly

environment

Mac OS python 3.8.5 plotly 4.12.0

pip, import Install the following from pip: I installed it together to use numpy in the article.

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

plotly slider basics

Although it is officially listed, for the time being

See the Pen simple slider by shunta-m (@shunta-m) on CodePen.

It is written in the order of trace (plot) creation-> layout creation-> graph creation

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

#List to save the plot
data = []
x = np.linspace(0, 10, 101)
#Creating a plot
# 0, 0.1, ... ,Create plots up to 5
for step in np.linspace(0, 5, 51):
    y = np.sin(step * x)

    trace = go.Scatter(
        x=x,
        y=y,
        name="sin step{:.1f}".format(step),
        line=dict(color="red", width=3),
        visible=False, )  #Make it invisible
    data.append(trace)

#Make the 10th plot visible as an initial state
data[10].visible = True

#Where to display by the position of the slider/List to hide or save
steps = []
"""
Decide where to see in the for statement
For example, when the slider is at 10, I just want to see the 10th plot.
Hide everything once->Set visible on the 10th plot to True to make it visible
"""
for s in range(len(data)):
    step = dict(method="update",
                args=[{"visible": [False] * len(data)},  #Hide everything once
                      {"title": "Simple slider step: {}".format(s)}]  #Change the title depending on the position of the slider
                )
    step["args"][0]["visible"][s] = True  #Make only the corresponding ones visible
    #Added a layout created in ↑ that only the sth can be seen to steps
    steps.append(step)

sliders = [dict(
    active=10,  #Initial value of slider
    currentvalue=dict(prefix="Frequency: "),
    pad=dict(t=50),  #Slider occupancy range,The larger the value, the larger the slider range.
    steps=steps)]  #Display that steps have/Use hidden information

layout = go.Layout(
    title="Simple slider step: 10",  #Initial title
    xaxis=dict(title="x"),
    yaxis=dict(title="y"),
    font=dict(family="Meiryo", size=16),  #Font in graph to Meiryo, size to 16
    #Hover mode (how the numbers look when you move the cursor closer to the graph)
    #The strings that can be given"x", "y", "closest", False, "x unified", "y unified"
    hovermode="x unified",
    hoverlabel=dict(font_size=16),  #Hover mode font size setting
    sliders=sliders,  #Slider added
    showlegend=True)  #Legend display set to True

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

#output
offline.plot(fig, auto_open=True, include_plotlyjs="cdn", filename="simple_slider.html")

Move multiple plots

Let's move both sine wave and cos wave.

plots.gif

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 = []
"""
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 making it sin,Allows both cos to display the trace at address 2
"""
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(family="Meiryo", 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")

Move some plots

When there are things you want to move with the slider and things you do not want to move in the same graph

plots2.gif

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

data = []
sin_data, cos_data = [], []
x = np.linspace(0, 10, 101)

#Fixed plot
trace = go.Scatter(
    x=x,
    y=2 * np.cos(x),
    name="2 * cos",
    line=dict(color="green", width=3),
    visible=True, )
data.append(trace)  #The 0th of data is fixed plot information

#Slider plot
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 = []
"""
Always show fixed plots, so make visible always True
    ->0th of data(Fixed plot)To True
"""
for s in range(len(sin_data)):
    sin_visible, cos_visible = [False] * len(sin_data), [False] * len(cos_data)
    sin_visible[s], cos_visible[s] = True, True
    step = dict(method="update",
                args=[{"visible": [True] + sin_visible + cos_visible},  #0th is always True
                      {"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(family="Meiryo", 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="plot2.html")

Hide from the middle

Cos disappears when the slider reaches 40 or higher.

plots3.gif

When it is 40 or more, the x and y values of cos_trace are simply set to None.

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

x = np.linspace(0, 10, 101)

data = []
sin_data, cos_data = [], []

trace = go.Scatter(
    x=x,
    y=2 * np.cos(x),
    name="2 * cos",
    line=dict(color="green", width=3),
    visible=True, )
data.append(trace)

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, )

    if step < 4:
        cos_trace = go.Scatter(
            x=x,
            y=y2,
            name="cos {:.1f}Hz".format(step),
            line=dict(color="blue", width=3),
            visible=False, )
    else:
        cos_trace = go.Scatter(x=None, y=None)  #4 or more is None

    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 = []
for s in range(len(sin_data)):
    sin_visible, cos_visible = [False] * len(sin_data), [False] * len(cos_data)
    sin_visible[s], cos_visible[s] = True, True
    step = dict(method="update",
                args=[{"visible": [True] + 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(family="Meiryo", 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="plots3.html")

Reference site

Official site Plotly Python Graphing Library | Python | Plotly

codepen Check the drawing result using Plotly by embedding CodePen in Qiita --Qiita CodePen can now be embedded in articles in Qiita-Qiita

Recommended Posts

Application of graphs with plotly sliders
Publish nice graphs online with plotly
Candlestick with plotly + Jupyter
3D display with plotly
Overlay graphs with sympy
Application of Python 3 vars
Introducing the potential of Plotly scatter plots with practical examples
Candle chart plot with plotly
Use directional graphs with networkx
Web application development with Flask
WebSocket application with Flask-Socket IO
Real-time graphs on Plotly (Python)
Web application creation with Django
Parallel processing with Parallel of scikit-learn
Application of CNN2 image recognition
Prediction of Nikkei 225 with Pytorch 2
Memories of fighting with Selenium
Prediction of Nikkei 225 with Pytorch
Web application with Python + Flask ② ③
Animate multiple graphs with matplotlib
Rails application building with Docker
Web application with Python + Flask ④
[Understanding / application of with syntax] Flexible switching of Python standard output destination
[Talking about the drawing structure of plotly] Dynamic visualization with plotly [python]
Test the application of migration files with Django + PostgreSQL (Evil Way)