簡體   English   中英

Plotly:如何為每個變量創建具有不同樣式和顏色的線圖?

[英]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()子集的示例

情節 1

在此處輸入圖片說明

代碼 1

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

但是您似乎也對不同形狀的標記感興趣,而且似乎沒有像colorline_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)]
  • 用於為 DataFrame 中的每一列生成不同標記和線條樣式的代碼。
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.

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