![](/img/trans.png)
[英]Plotly: How to create a line plot of a time series variable that has a multiple-color label?
[英]Plotly: How to create a line plot with different style and color for each variable?
我正在嘗試使用 Plotly express 創建一個具有 10 條不同顏色和標記的不同線條的圖形。 類似的東西:
我可以使用文檔建議的px.line
函數創建具有不同顏色的漂亮圖形。 我的代碼如下所示:
import plotly.express as px
import numpy as np
import pandas as pd
rand_elems = []
for i in range(10):
rand_elems.append(np.random.randn(25))
data = pd.DataFrame(rand_elems)
px.line(data_frame=data.T)
我的折線圖如下所示:
其中每個變量是一個 (25,) numpy 數組,其隨機值來自標准正態分布(使用np.random.randn(25)
創建)。
有沒有辦法可以為每一行添加不同的樣式? 也歡迎其他繪圖庫,因為我在 Plotly 的文檔中找不到解決方案。
我知道我可以使用的線條樣式是有限的。 也許我可以循環瀏覽它們和顏色? 對此有什么好的解決方案?
編輯:該圖的目的只是為了表明信號是隨機的並且在標准正態分布范圍內。
px.line
非常適合高度多樣性的數據集,例如跨越幾個大洲的一系列國家/地區的不同類別,因為您可以使用諸如color = 'country
, line_dash = 'continent
來為它們分配顏色和形狀來區分類別。 這是一個使用內置數據集px.data.gapminder()
子集的示例
import plotly.express as px
from plotly.validators.scatter.marker import SymbolValidator
# data
df = px.data.gapminder()
df = df[df['country'].isin(['Canada', 'USA', 'Norway', 'Sweden', 'Germany'])]
# plotly
fig = px.line(df, x='year', y='lifeExp',
color='country',
line_dash = 'continent')
fig.show()
但是您似乎也對不同形狀的標記感興趣,而且似乎沒有像color
和line_shape
那樣易於使用的內置功能。 因此,接下來是一種循環瀏覽可用標記形狀並將其應用於例如不同國家的方法。 您當然可以通過從標記樣式中選擇形狀來定義自己的序列,例如:
['arrow-bar-left', 'asterisk', 'arrow-right', 'line-ne', 'circle-cross', 'y-left']
但是您也可以根據raw_symbols = SymbolValidator().values
獲取一堆樣式, raw_symbols = SymbolValidator().values
改進這些發現並將它們添加到例如國家/地區名稱中。
這是結果
這是你如何做到的:
import plotly.express as px
from itertools import cycle
# data
df = px.data.gapminder()
df = df[df['country'].isin(['Canada', 'USA', 'Norway', 'Sweden', 'Germany'])]
# plotly
fig = px.line(df, x='year', y='lifeExp',
color='country',
line_dash = 'continent')
# retrieve a bunch of markers
raw_symbols = SymbolValidator().values
namestems = []
namevariants = []
symbols = []
for i in range(0,len(raw_symbols),3):
name = raw_symbols[i+2]
symbols.append(raw_symbols[i])
namestems.append(name.replace("-open", "").replace("-dot", ""))
namevariants.append(name[len(namestems[-1]):])
markers = cycle(list(set(namestems)))
# set unique marker style for different countries
fig.update_traces(mode='lines+markers')
for d in fig.data:
d.marker.symbol = next(markers)
d.marker.size = 10
fig.show()
我已經采用了 @vestland 的代碼,並改編並修復了一個更簡單的版本,它完全符合我的需要。 這個想法是使用來自plotly.validators.scatter.marker
SymbolValidator()
,如@vestland 的回答中所述。 還可以在此列表中添加一個隨機因素以獲得更不同的結果。
示例運行代碼:
import plotly.express as px
from itertools import cycle
from plotly.validators.scatter.marker import SymbolValidator
# data
df = px.data.gapminder()
df = df[df['country'].isin(['Canada', 'USA', 'Norway', 'Sweden', 'Germany'])]
# plotly
fig = px.line(df, x='year', y='lifeExp',
color='country',
line_dash = 'continent')
raw_symbols = SymbolValidator().values
# Take only the string values which are in this order.
symbols_names = raw_symbols[::-2]
markers = cycle(symbols_names)
# set unique marker style for different countries
fig.update_traces(mode='lines+markers')
for d in fig.data:
d.marker.symbol = next(markers)
d.marker.size = 10
fig.show()
此代碼生成以下圖形: 非常感謝@vestland 的見解,我想知道 Plotly 是否可以在下一個版本中將此作為參數選項。
更新:
如果您的 DataFrame 沒有像我一樣用於line_dash
參數的聚合列,您還可以循環瀏覽帶有線型的列表,並使用 `fig.data.line["dash"] 覆蓋它們,如下所示:
import numpy as np
import random
import plotly.express as px
import numpy as np
import pandas as pd
from itertools import cycle
from random import shuffle
from plotly.validators.scatter.marker import SymbolValidator
from plotly.validators.scatter.line import DashValidator
rand_elems = []
for i in range(10):
rand_elems.append(np.random.randn(25))
data = pd.DataFrame(rand_elems)
data.index = [f"Signal {i}" for i in range(10)]
line_styles_names = ['solid', 'dot', 'dash', 'longdash', 'dashdot', 'longdashdot']
line_styles = cycle(line_styles_names)
fig = (px.line(data_frame=data.T,
color_discrete_sequence=px.colors.qualitative.Bold_r,
title="First 10 Signals Visualization",
))
symbols_names = list(set([i.replace("-open", "").replace("-dot", "") for i in SymbolValidator().values[::-2]]))
shuffle(symbols_names)
markers = cycle(symbols_names)
_ = fig.update_traces(mode='lines+markers')
for d in fig.data:
d.line["dash"] = next(line_styles)
d.marker.symbol = next(markers)
d.marker.size = 10
fig.show()
我知道的方法是為要繪制的每條線創建單獨的圖形對象(每條線都有自己的樣式)。 然后創建所有圖形對象的列表並將其傳遞給 go.Figure() 函數的data
參數。
有關示例,請參閱此博客。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.