2 回答

TA貢獻1873條經(jīng)驗 獲得超9個贊
第二個建議
(請進一步閱讀我的第一個建議,了解一些假設(shè)和條件)
我已經(jīng)成功地建立了一種方法,它幾乎應(yīng)該涵蓋您在這里所要求的所有內(nèi)容。提供真正挑戰(zhàn)的唯一細(xì)節(jié)是如何可視化跡線之間的間隙,因為我的第二個建議建立在為每個單獨的跡線添加唯一跡線的基礎(chǔ)上label
。您可能懷疑這可能會用一堆重復(fù)的名稱填充圖例,但這是通過按關(guān)聯(lián)標(biāo)簽對跟蹤名稱進行分組來解決的。我還建立了一個字典,您可以在其中指定每個標(biāo)簽的顏色。這是結(jié)果:
圖 2.1 - 由標(biāo)簽定義的顏色
注意到灰色線了嗎?這就是我之前描述的“連接性”問題的結(jié)果。您可以通過設(shè)置 中的不透明度參數(shù)(最后一個數(shù)字)來選擇隱藏或顯示該行color='rgba(200,200,200,0.2)'
。您將在下面找到一個完整的代碼片段來重現(xiàn)該圖。有很多事情需要對整個事情進行調(diào)整,所以如果有任何不清楚的地方,請隨時詢問細(xì)節(jié)。
完整代碼:
# imports
import plotly.express as px
import plotly.graph_objects as go
import pandas as pd
import numpy as np
import random
# settings
observations = 100
np.random.seed(5)
value = np.random.uniform(low=-1, high=1, size=observations).tolist()
time = [t for t in pd.date_range('2020', freq='D', periods=observations)]#.format()]
df=pd.DataFrame({'time': time,
'value':value})
df['value']=df['value'].cumsum()
df1 = df.copy()
df1=df1.set_index('time')
# custom function to build labels as conditions of parameter values
def classify(e):
if e > 0.75: return 'high'
if e > 0.25: return 'medium'
if e >= 0: return 'low'
# custom function to set mode = line or marker, given data length
def modes(df):
if len(df) > 1: return 'lines'
else: return 'markers'
# dictionary to specify marker or line color
# this will depend on your real world labels !!!
cols = {'high': 'green',
'medium': 'blue',
'low': 'red'}
df['label1'] = [(elem-df['value'].min())/(df['value'].max()-df['value'].min()) for elem in df['value']]
df['label'] = [classify(elem) for elem in df['label1']]
df = df.drop('label1', 1)
df['group'] = df['label'].ne(df['label'].shift()).cumsum()
df = df.groupby('group')
dfs = []
for name, data in df:
dfs.append(data)
fig = go.Figure()
# one line to connect them all
fig=go.Figure((go.Scatter(x=df1.index, y=df1['value'],
name = 'all data',
line=dict(color='rgba(200,200,200,0.7)'))))
showed = []
for frame in dfs:
if frame['label'].iloc[0] not in showed:
fig.add_trace(go.Scatter(x=frame['time'], y = frame['value'],
mode = modes(frame),
marker_color = cols[frame['label'].iloc[0]],
legendgroup=frame['label'].iloc[0],
name=frame['label'].iloc[0]))
showed.append(frame['label'].iloc[0])
else:
fig.add_trace(go.Scatter(x=frame['time'], y = frame['value'],
mode = modes(frame),
marker_color = cols[frame['label'].iloc[0]],
legendgroup=frame['label'].iloc[0],
name=frame['label'].iloc[0],
showlegend=False
))
fig.update_layout(template='plotly_dark')
fig.update_xaxes(showgrid=False)
fig.update_layout(uirevision='constant')
fig.show()
第一個建議
您應(yīng)該如何執(zhí)行此操作在很大程度上取決于數(shù)據(jù)集的結(jié)構(gòu)。根據(jù)你的問題的聲音,我只能猜測它看起來像這樣:
time param label
0 2020-01-01 -0.556014 medium
1 2020-01-02 0.185451 high
2 2020-01-03 -0.401111 medium
3 2020-01-04 0.436111 high
4 2020-01-05 0.412933 high
5 2020-01-06 0.636421 peak
6 2020-01-07 1.168237 peak
7 2020-01-08 1.205073 peak
8 2020-01-09 0.798674 peak
9 2020-01-10 0.174116 high
param如果是這樣,那么如果您想用不同顏色的線條軌跡進行顯示,您很快就會遇到數(shù)據(jù)點之間奇怪的連接問題。我想到的第一件事是將一種顏色的線條與多種顏色的標(biāo)記相結(jié)合,如下所示:
這將為您提供良好的交互性,您可以在其中打開和關(guān)閉所有元素,也許只研究數(shù)據(jù)中的以下部分label=='peak
:
讓我知道這對您來說效果如何,我們可以討論更多細(xì)節(jié)。您可以在此處找到數(shù)據(jù)樣本和所有詳細(xì)信息:
完整代碼:
# imports
import plotly.express as px
import plotly.graph_objects as go
import pandas as pd
import numpy as np
import random
# settings
observations = 100
np.random.seed(5); cols = list('a')
param = np.random.uniform(low=-1, high=1, size=observations).tolist()
time = [t for t in pd.date_range('2020', freq='D', periods=observations).format()]
df=pd.DataFrame({'time': time,
'param':param})
df['param']=df['param'].cumsum()
def classify(e):
if e > 0.9: return 'peak'
if e > 0.75: return 'high'
if e > 0.25: return 'medium'
if e > 0.9: return 'low'
if e >= 0: return 'bottom'
df['label1'] = [(elem-df['param'].min())/(df['param'].max()-df['param'].min()) for elem in df['param']]
df['label'] = [classify(elem) for elem in df['label1']]
df = df.drop('label1', 1)
fig=go.Figure((go.Scatter(x=df['time'], y=df['param'],
mode='lines',
line=dict(color='rgba(0,0,200,0.7)'))))
fig.add_traces(px.scatter(df, x='time', y='param', color='label').data)
fig.update_layout(template='plotly_dark')
fig.update_xaxes(showgrid=False)
fig.show()

TA貢獻1831條經(jīng)驗 獲得超9個贊
如果我理解正確,您正在嘗試?yán)L制具有兩個不同顏色標(biāo)簽的單個時間序列數(shù)據(jù)。在同一個圖中繪制多條線會導(dǎo)致一些重疊,因為它共享時間軸。
為什么不使用散點圖(不連接點)?根據(jù)數(shù)據(jù)的密度,這在視覺上看起來類似于連接的直線/曲線。
您還可以嘗試?yán)L制藍(lán)線和紅線并進行一些垂直移動以減少重疊。
添加回答
舉報