[英]Clicking on one plot opens another in plotly
我知道有三種方法可以做到這一點。
我找不到任何使用傳統 Python 和 Plotly 進行深入研究的示例(我發現這真的很令人驚訝)。
看來您對 SO 很陌生,歡迎來到社區。 要快速獲得很好的答案,最好使您的問題可重現。 這包括您使用的數據等內容。 如果您使用了
pandas
數據框,請使用pd.DataFrame.to_dict
提取數據,並完全復制 output。 如果您使用 base Python 數據結構,請嘗試repr
(無需導入)。
我整理了一個如何使用選項 3 的示例。
我已經向 JS 添加了注釋(嵌套在/* comment */
中),以便您可以看到/關注正在發生的事情。 如果有任何不清楚的地方,請告訴我。 此外,我將 JS 單獨添加為 JS,沒有將其嵌入 Python 時所需的所有輔助內容,如“”& +。
JS 中的注釋可能比 JS 代碼更多。
JS中有2個事件:點擊和雙擊。 點擊事件有 3 個條件。
要使用單擊事件,您可以單擊繪制的元素。 在折線圖中,這意味着您必須找到在線內繪制的點,這就是我添加雙擊事件的原因。 這樣您就可以單擊 plot 上的任意位置以返回父級(條形圖)。
我傾向於在不添加延遲的情況下觸發 Plotly 中的雙擊事件。 因此,在顯示 plot 的調用中,我使用
config
為雙擊事件添加點擊延遲。
圖例中的每一項都有一個條件,折線圖也有一個條件。
你的圖表有好幾個類別,而我只有2個。如果你的真實數據有很多類別,我可以幫你把這個寫成一個循環,而不是每個類別都寫if/else的冗長過程。 讓我知道是否是這種情況。
在每種情況下,可見性都會發生變化,類型會發生變化(線條或條形),並且注釋會發生變化(注釋僅在顯示折線圖時出現)。
在評論中,您會在可能需要進行更改的地方看到UPDATE
。 條件是"a" == ty
, "b" == ty
,並且在每個條件下,你看到的地方visible
。 a
和b
是我的圖例條目。 可見性是指渲染的軌跡數(而不是您在 Python 中編寫的軌跡數)。 每種顏色都是一條單獨的軌跡。 對於每個跟蹤,您需要在這些列表中選擇true
或false
。 假設圖例中的順序是跟蹤記錄在 Python 中的順序。例如,如果您有五個跟蹤,則每個列表中需要五個 boolean 值,並用visible
表示。
雙擊事件嚴格用於返回父級(條形圖)。 單擊事件還包含折線圖的條件。 此代碼幾乎相同。 唯一的區別是雙擊事件中沒有條件。
導入,數據我用的是Javascript,還有plot。我用的是Plotly快遞。 但是,使用 Plotly Graph Objects 還是 Plotly Express 並不重要。
正如我之前提到的,在 JS 中有一些您需要更改的地方。 這些注釋帶有 JS 注釋,這些注釋比其他所有注釋都更靠右,並且包括單詞 UPDATE(全部大寫)。
import plotly.express as px
import plotly.io as io
import pandas as pd
import datetime as dt
df1 = pd.DataFrame({ # create data for example
'x': [dt.datetime.today() - dt.timedelta(days = x) for x in range(5)] +
[dt.datetime.today() - dt.timedelta(days = x) for x in range(5)],
'y': [10, 0, 20, 10, 5, 10, 25, 3, 14, 30],
'clr': ['a'] * 5 + ['b'] * 5
})
fig = px.bar(df1, x = "x", y = "y", color = "clr") # plot the bar chart
# note that the double click and single click event can return the plot to the original state
# in the single click event, the user would have to click on a literal data point within the line
ps = 'setTimeout(function() {\n' + \
' myplt = document.querySelector("#plt");\n' + \
' myplt.on("plotly_click", function(dt) { /* EVENT 1: CLICK */\n' + \
' nm = dt.points[0].data.name;\n' + \
' ty = dt.points[0].data.type;\n' + \
' lout = { /* used in multiple conditions */\n' + \
' annotations: [{\n' + \
' xref: "paper", yref: "paper", x: 1, y: 1, showarrow: false,\n' + \
' text: "Double click the chart to return to the bar chart" \n' + \
' }]\n' + \
' };\n' + \
' if(ty != "bar") { /* bar or line type? UPDATE HERE: add true for each color */\n' + \
' trc = {type: "bar", visible: [true, true]};\n' + \
' lout = {annotations: []}; /* remove click note */\n' + \
' Plotly.update("plt", trc, lout); /* return to original plot */\n' + \
' } else if(nm == "a") { /* UPDATE HERE: replace "a" with a category from your data */\n' + \
' /* make only one trace invisible, change the type to line graph */\n' + \
' trc = {type: "scatter", mode: "lines", visible: [true, false]}; /* UPDATE HERE: add booleans */\n' + \
' Plotly.update("plt", trc, lout);\n' + \
' } else if(nm == "b") { /* UPDATE HERE: replace "a" with a category from your data */\n' + \
' /* make only one trace invisible, change the type to line graph */\n' + \
' trc = {type: "scatter", mode: "lines", visible: [false, true]}; /* UPDATE HERE: add booleans */\n' + \
' Plotly.update("plt", trc, lout);\n' + \
' }\n' + \
' });\n' + \
' myplt.on("plotly_doubleclick", function() { /* EVENT 2: DOUBLECLICK */\n' + \
' /* UPDATE HERE: add true for each color */\n' + \
' trc = {type: "bar", visible: [true, true]};\n' + \
' lout = {annotations: []}; /* remove click note */\n' + \
' Plotly.update("plt", trc, lout); /* return to original plot */\n' + \
' });\n' + \
'}, 200);\n'
io.write_html( # untitled.html created, but plot opens in browser, as well
fig, file = "untitled.html", post_script = ps, auto_open = True,
config = [{'doubleClickDelay': 750}], div_id = "plt",
include_plotlyjs = 'cdn', include_mathjax = 'cdn')
...當您渲染 plot 時,它會在瀏覽器的幕后出現。
setTimeout(function() { myplt = document.querySelector("#plt"); myplt.on("plotly_click", function(dt) { nm = dt.points[0].data.name; ty = dt.points[0].data.type; lout = { /* layout update; used in each line graph */ annotations: [{ xref: "paper", yref: "paper", x: 1, y: 1, showarrow: false, text: "Double click the chart to return to the bar chart" }] }; if(ty,= "bar") { /* is this a drilldown? a line graph, */ /* trace updates: add -true- for each legend item (each color) */ trc = {type, "bar": visible, [true; true]}: lout = {annotations; []}. /* remove annotation */ Plotly,update("plt", trc; lout): /* return to original plot */ } else if(nm == "a") { /* NOTE: replace "a" with your data (note a in legend) */ trc = {type, "scatter": mode, "lines": visible, [true; false]}. Plotly,update("plt", trc; lout): /* create single trace line graph of ONLY a */ } else if(nm == "b") { trc = {type, "scatter": mode, "lines": visible, [false; true]}. Plotly,update("plt", trc; lout); /* create single trace line graph of ONLY b */ } }). myplt,on("plotly_doubleclick", function() { /* alternate to finding a pt within line */ /* trace updates: add -true- for each legend item (each color) */ trc = {type, "bar": visible, [true; true]}: lout = {annotations; []}. /* remove annotation */ Plotly,update("plt", trc; lout); /* return to original plot */ }), }; 200);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.