Plotly:如何使用下拉菜单选择图形源?

Posted

技术标签:

【中文标题】Plotly:如何使用下拉菜单选择图形源?【英文标题】:Plotly: How to select graph source using dropdown? 【发布时间】:2018-03-06 17:59:32 【问题描述】:

我正在尝试使用 Plotly 使用下拉图在单个图中嵌入多个可选择的图形。我遵循了 Plotly 的 dropdown example,但它们只显示了如何更改图形特征(如可见或类型),而不是基础数据。在我的情况下,我有一个静态 X 轴并想要更改 Y 值。这是一个可以在 jupyter notebook 中运行的最小工作示例:

import plotly
from plotly import graph_objs as go, offline as po, tools
po.init_notebook_mode()

import numpy as np
import json

x = list(np.linspace(-np.pi, np.pi, 100))
values_1 = list(np.sin(x))
values_2 = list(np.tan(x))

line = go.Scatter(
    x=x,
    y=values_1
)

updatemenus = [
    
        'buttons': [
            
                'method': 'restyle',
                'label': 'Val 1',
                'args': [
                    'y': json.dumps(values_1),
                ]
            ,
            
                'method': 'restyle',
                'label': 'Val 2',
                'args': [
                    'y': json.dumps(values_2),
                ]
            
        ],
        'direction': 'down',
        'showactive': True,
    
]

layout = go.Layout(
    updatemenus=updatemenus,
)

figure = go.Figure(data=[line], layout=layout)

po.iplot(figure)

然而,虽然该方法似乎像宣传的一般图形属性(如“可见”)一样工作,但当我使用“y”时,它会产生一条直线,其中 y 从 0 变为 len(y),而不是我给它的实际数据。这是初始渲染的图像,然后是当我选择 Tan(X) 图的下拉项,然后返回 Sin(X) 时会发生什么:

如何将多个图表的数据嵌入到单个图表中,以便用户可以选择他们想要查看的图表?

【问题讨论】:

【参考方案1】:

使用 graph_objects 更新答案:

从version 4 开始,您不必担心离线与在线功能。所以放弃from plotly import graph_objs as go, offline as popo.init_notebook_mode(),直接使用import plotly.graph_objects as go。我已经用完整的代码 sn-p 更新了我的原始答案,该代码显示了整个方法,multiple 在末尾使用plotly.graph_objects 跟踪。仍然存在的问题的解决方案仍然是相同的,即:


'y' in updatemenus 不接受单个列表作为参数,而是像'y' = [values_1] 中的列表列表,其中values_1 是一个列表本身。所以只需替换你的行

'y': json.dumps(values_1),'y': json.dumps(values_2),

'y': [values_1],'y': [values_2],

获取不同选项Val 1Val 2 的这些图:



一些细节:

Values_1 毫无疑问是一个长度为 100 的列表,其中每个元素的类型都是 numpy.float。将json.dumps(values_1) 替换为values_1,将json.dumps(values_2) 替换为values_2 将呈现与您的问题相同的图。这些图只是直线的原因似乎是正在绘制的列表的长度,而不是该列表中包含的值。或者类似的东西。

设置'y' = values_1 与将单个 列表分配给'y' 相同。但是updatemenus 中的'y' 不会将单个列表作为参数,而是使用'y' = [values_1] 中的列表列表。为什么?因为您可能想在同一图中绘制多个列表,例如'y' = [values_1, values_1b]。看看:

绘制下拉选项 Var 1:

绘制下拉选项 Var 2

完整原代码:

import plotly
from plotly import graph_objs as go, offline as po, tools
po.init_notebook_mode()

import numpy as np
import json

x = list(np.linspace(-np.pi, np.pi, 100))
values_1 = list(np.sin(x))
values_1b = [elem*-1 for elem in values_1]

values_2 = list(np.tan(x))
values_2b = [elem*-1 for elem in values_2]


line = go.Scatter(
    x=x,
    y=values_1
)

line2 = go.Scatter(
    x=x,
    y=values_1b
)


updatemenus = [
    
        'buttons': [
            
                'method': 'restyle',
                'label': 'Val 1',
                'args': [
                    'y': [values_1, values_1b],
                ]
            ,
            
                'method': 'restyle',
                'label': 'Val 2',
                'args': [
                    'y': [values_2, values_2b],
                ]
            
        ],
        'direction': 'down',
        'showactive': True,
    
]

layout = go.Layout(
    updatemenus=updatemenus,
)

figure = go.Figure(data=[line, line2], layout=layout)
po.iplot(figure)

完整更新代码:

# imports
import plotly.graph_objects as go
import numpy as np

# data
x = list(np.linspace(-np.pi, np.pi, 100))
values_1 = list(np.sin(x))
values_1b = [elem*-1 for elem in values_1]
values_2 = list(np.tan(x))
values_2b = [elem*-1 for elem in values_2]

# plotly setup]
fig = go.Figure()

# Add one ore more traces
fig.add_traces(go.Scatter(x=x, y=values_1))
fig.add_traces(go.Scatter(x=x, y=values_1b))

# construct menus
updatemenus = ['buttons': ['method': 'update',
                             'label': 'Val 1',
                             'args': ['y': [values_1, values_1b],]
                              ,
                            'method': 'update',
                             'label': 'Val 2',
                             'args': ['y': [values_2, values_2b],]],
                'direction': 'down',
                'showactive': True,]

# update layout with buttons, and show the figure
fig.update_layout(updatemenus=updatemenus)
fig.show()

使用版本 4 默认布局进行绘图:

【讨论】:

是否可以对散点图标记的大小和颜色设置做类似的事情?我正在尝试从带有下拉列表的数据框中选择列,以用于 plotly express 中的 scatter 和 scatter_3d 。我可以让它与 ipywidgets 一起工作,但没有情节内置。 @GordonWells 是的!但请考虑把它写成一个新问题。

以上是关于Plotly:如何使用下拉菜单选择图形源?的主要内容,如果未能解决你的问题,请参考以下文章

Plotly:如何使用下拉菜单过滤熊猫数据框?

如何命名 Dash/Plotly 中的下拉菜单

使用下拉菜单在 Plotly 中交互式过滤数据表

plotly:使用下拉选择更新数据

Plotly交互式绘图python:将下拉菜单更改为输入框

在shiny中用现有的plotly情节创建下拉菜单。