python - Plotly:如何使用类似于在图例中单击它们的按钮来切换轨迹?
问题描述
我正在使用 python 并创建带有交互式绘图的独立 html 文件(没有 Dash)。我已经能够构建一个带有按钮的绘图图,这些按钮可以切换图中迹线的可见性。但是,此功能也会从图例中删除痕迹。我想要的是能够保留图例的功能(单击单个跟踪以切换可见性),而且还有一组按钮可以将该功能扩展到我定义的一组跟踪。
目标是能够将所有内容(或选择的组)切换为不可见,但根据需要将该组中的单个项目添加回可见。
下面是一个示例(使用来自vestland这个答案的修改代码)来显示我目前正在尝试的内容。
import numpy as np
import pandas as pd
import plotly.graph_objects as go
import datetime
# mimic OP's datasample
NPERIODS = 200
np.random.seed(123)
df = pd.DataFrame(np.random.randint(-10, 12, size=(NPERIODS, 4)),
columns=list('ABCD'))
datelist = pd.date_range(datetime.datetime(2020, 1, 1).strftime('%Y-%m-%d'),
periods=NPERIODS).tolist()
df['dates'] = datelist
df = df.set_index(['dates'])
df.index = pd.to_datetime(df.index)
df.iloc[0] = 0
df = df.cumsum()
# set up multiple traces
traces = []
buttons = []
for col in df.columns:
traces.append(go.Scatter(x=df.index,
y=df[col],
visible=True,
name=col)
)
buttons.append(dict(method='update',
label=col,
visible=True,
args=[{'visible':[x == col for x in df.columns]}],
args2=[{'visible':[x != col for x in df.columns]}]
)
)
# create the layout
layout = go.Layout(
updatemenus=[
dict(
type='buttons',
direction='right',
x=0.7,
y=1.3,
showactive=True,
buttons=buttons
)
],
title=dict(text='Toggle Traces',x=0.5),
showlegend=True
)
fig = go.Figure(data=traces,layout=layout)
# add dropdown menus to the figure
fig.show()
该示例无法按我的意愿工作。下面是它最初的样子的屏幕截图。
问题是,如果我使用其中一个按钮,它会隐藏所有其他痕迹,但也会将它们从图例中删除,因此无法将它们切换回可见状态。
所以我的问题变成了,在 args 列表/字典中是否有不同的值可以提供与简单地单击图例中的跟踪相匹配的功能?
有点相关,有什么方法可以获取每个跟踪的当前可见性状态吗?
解决方案
为了能够在不影响其他跟踪的情况下打开和关闭任何跟踪,看来您必须为每个按钮包含一个更新菜单。可能还有其他方法可以做到这一点,但下面的代码片段将产生以下情节:
情节 1 - 启动时全部被选中
情节 2 -C
并D
关闭
情节 3 - 全部off
情节 4 - 全部on
完整代码:
import numpy as np
import pandas as pd
import plotly.graph_objects as go
import datetime
import plotly.express as px
periods = 200
cols = list('ABCD')
np.random.seed(123)
df = pd.DataFrame(np.random.randint(-10, 12, size=(periods, len(cols))),
columns=cols)
datelist = pd.date_range(datetime.datetime(2020, 1, 1).strftime('%Y-%m-%d'),
periods=periods).tolist()
df['dates'] = datelist
df = df.set_index(['dates'])
df.index = pd.to_datetime(df.index)
df.iloc[0] = 0
df = df.cumsum()
# # plotly
fig = go.Figure()
colors = px.colors.qualitative.Plotly
# set up multiple traces
for col in df.columns:
fig.add_trace(go.Scatter(x=df.index,
y=df[col],
name = col,
visible=True
)
)
um = [ {} for _ in range(len(df.columns)) ]
buttons = []
menuadjustment = 0.15
buttonX = -0.1
buttonY = 1 + menuadjustment
for i, col in enumerate(df.columns):
button = dict(method='restyle',
label=col,
visible=True,
args=[{'visible':True,
'line.color' : colors[i]}, [i]],
args2 = [{'visible': False,
'line.color' : colors[i]}, [i]],
)
# adjust some button features
buttonY = buttonY-menuadjustment
um[i]['buttons'] = [button]
um[i]['showactive'] = False
um[i]['y'] = buttonY
um[i]['x'] = buttonX
# add a button to toggle all traces on and off
button2 = dict(method='restyle',
label='All',
visible=True,
args=[{'visible':True}],
args2 = [{'visible': False}],
)
# assign button2 to an updatemenu and make some adjustments
um.append(dict())
um[i+1]['buttons'] = [button2]
um[i+1]['showactive'] = True
um[i+1]['y']=buttonY - menuadjustment
um[i+1]['x'] = buttonX
# add dropdown menus to the figure
fig.update_layout(showlegend=True, updatemenus=um)
# adjust button type
for m in fig.layout.updatemenus:
m['type'] = 'buttons'
f = fig.full_figure_for_development(warn=False)
fig.show()
推荐阅读
- amazon-web-services - 适用于 EC2、EMR、Redshift、RDS 的 AWS 开发工具包用例
- java - 面对 java.lang.ClassNotFoundException: org.springframework.web.servlet.DispatcherServlet
- go - 即使我得到一个着色器编译错误,所有着色器都可以正常工作。如何?
- css - 带有重复修饰符的 CSS 后代选择
- python - 如何在不更改任何默认值的情况下在 Ubuntu 上为 python 3.8 安装 pip?
- docker - 如何使用 docker compose 指定 GPU 限制 docker swarm?
- python - “is” Python 运算符是否可靠地测试可变对象的引用相等性?
- c++ - 为什么在我的程序中找不到 dll 的入口点?文件
- python - 当我尝试向用户添加 exp 时,我收到 KeyError: '563690668808208423'
- javascript - 无法使用 Firebase 云功能发送电子邮件