簡體   English   中英

Plotly:如何使用類似於在圖例中單擊它們的按鈕來切換軌跡?

[英]Plotly: How to toggle traces with a button similar to clicking them in legend?

我正在使用 python 並創建帶有交互式繪圖(無破折號)的獨立 html 文件。 我已經能夠構建一個 plotly plot 按鈕,可以切換 plot 中跡線的可見性。 但是,此功能也會從圖例中刪除痕跡。 我想要的是能夠保留圖例的功能(單擊單個跟蹤以切換可見性),但也有一組按鈕將該功能擴展到我定義的一組跟蹤。

目標是能夠將所有內容(或 select 組)切換為不可見,但根據需要將該組中的單個項目添加回可見。

下面是一個示例(使用來自 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 列表/字典中是否有不同的值可以提供與簡單地單擊圖例中的跟蹤相匹配的功能?

有點相關,有什么方法可以讓每個跟蹤的當前 state 可見性?

為了能夠在不影響其他跟蹤的情況下打開和關閉任何跟蹤,看來您必須為每個按鈕包含一個更新菜單。 可能還有其他方法可以做到這一點,但下面的代碼片段將生成以下 plot:

Plot 1 - 啟動時全部選中

在此處輸入圖像描述

Plot 2 - CD關閉

在此處輸入圖像描述

Plot 3 - 全部off

在此處輸入圖像描述

Plot 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()

經過一番體面的搜索,由於 Plotly 論壇上的這個答案,我已經能夠弄清楚了。 我還沒有找到列出所有這些選項的地方,但這會很有幫助。

似乎在 args 字典中給予“可見”的列表不需要只是布爾值。 為了使項目在圖例中可見但隱藏在 plot 中,您需要將值設置為“legendonly”。 然后仍然可以單擊圖例條目來切換單個可見性。 這回答了我問題的主旨。

args = [{'visible': True}]
args = [{'visible': 'legendonly'}]
args = [{'visible': False}]

Vestland 的回答幫助解決了我的問題的第二部分,只修改了我想要的痕跡,而其他一切都保持不變。 事實證明,您可以將字典后的索引列表傳遞給 args,而這些 args 將僅適用於提供的索引處的跟蹤。 我在示例中使用列表理解來查找與給定名稱匹配的跟蹤。 我還為每一列添加了另一個跟蹤,以顯示這對多個跟蹤是如何工作的。

args = [{'key':arg}, [list of trace indices to apply key:arg to]]

下面是現在工作的代碼。

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)
                )
    traces.append(go.Scatter(x=df.index,
                y=df[col]+20,
                visible=True,
                name=col)
    )
    buttons.append(dict(method='restyle',
                        label=col,
                        visible=True,
                        args=[{'visible':True},[i for i,x in enumerate(traces) if x.name == col]],
                        args2=[{'visible':'legendonly'},[i for i,x in enumerate(traces) if x.name == col]]
                        )
                )

allButton = [
    dict(
        method='restyle',
        label=col,
        visible=True,
        args=[{'visible':True}],
        args2=[{'visible':'legendonly'}]
    )
]

# create the layout 
layout = go.Layout(
    updatemenus=[
        dict(
            type='buttons',
            direction='right',
            x=0.7,
            y=1.3,
            showactive=True,
            buttons=allButton + 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()

這提供了以下功能:

“全部”按鈕可以切換所有跡線的可見性。

每個其他按鈕只會切換具有匹配名稱的跟蹤。 這些痕跡在圖例中仍然可見,並且可以通過在圖例中單擊它們或再次單擊按鈕來恢復可見。

開始繪圖,所有痕跡都可見

單擊“B”按鈕后(兩次點擊 arg2)。

單擊 B 按鈕兩次后繪圖

然后單擊圖例中的第一個 B 跡線后。

再次啟用第一個 B 跟蹤后繪圖

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM