如何使用动态输入创建一致的 plotly 颜色图?

How to create a consistent plotly color map with dynamic input?

我有一些数据框,我想用可变数量的水果绘制。绘图时,每个数据框将始终具有相同的 Fruit 类型,即使某些数据框在其各自行中的值为 0。

df1
Day  Value Fruit
1    5     Banana
1    3     Pear
2    4     Banana
2    2     Pear
3    3     Banana
3    3     Pear

df2  # note all pears 0'd
Day  Value Fruit
1    5     Banana
1    0     Pear
2    4     Banana
2    0     Pear
3    3     Banana
3    0     Pear

# AKA
df1.Fruit.unique() == df2.Fruit.unique()

绘图代码:

import dash_bootstrap_components as dbc
from plotly import express as px

bar_charts = []
for df in dfs:
  # to get a stacked bar chart
  fruit_data = df.groupby(["Day", "Fruit"]).Value.sum().to_frame().reset_index()
  bar_charts.append(
    dcc.Graph(
      figure=px.bar(
        fruit_data,
        x="Day",
        y="Value",
        color="Fruit",
      ),
    )
  )
return dbc.Col(bar_charts)

Plotly 似乎根据水果的 为数据帧之间的水果分配不同的颜色。我希望 Fruits always 在图表中保持相同的颜色,而不管值如何(例如香蕉总是黄色,梨总是绿色)。但是,直到运行时我才知道哪些水果可用,所以我不能提前硬编码颜色图。

我如何巧妙地告诉水果颜色始终相同?

我确定这是我缺少的一些愚蠢的小选项。

要确保将相同的颜色分配给相同的 Fruit,您可以使用 fruit_data['Fruit'].unique() 和任何颜色列表(如 ['yellow', 'green'] 或更长的列表)制作颜色图px.colors.qualitative.Alphabet for color_discrete_map in px.bar 像这样:

colordict = {f:px.colors.qualitative.Alphabet[i] for i, f in enumerate(fruit_data.Fruit.unique())}
colordict = {f:['yellow', 'green'][i] for i, f in enumerate(fruit_data.Fruit.unique())}

剧情:

如果您正在处理大量变量并担心 运行 颜色不对,只需像这样合并 Plotly: How to increase the number of colors to assure unique colors for all lines 中描述的方法:

n_colors = len(fruit_data.Fruit.unique())
colorscale = colors = px.colors.sample_colorscale("viridis", [n/(n_colors -1) for n in range(n_colors)])
colordict = {f:colorscale[i] for i, f in enumerate(fruit_data.Fruit.unique())}

完整代码:

import io
import plotly.express as px
import pandas as pd

# data
fruit_data = pd.read_csv(io.StringIO("""Day  Value Fruit
                                1    5     Banana
                                1    3     Pear
                                2    4     Banana
                                2    2     Pear
                                3    3     Banana
                                3    3     Pear"""),sep= '\s+')

# color assignment:
# colordict = {f:px.colors.qualitative.Alphabet[i] for i, f in enumerate(fruit_data.Fruit.unique())}
colordict = {f:['yellow', 'green'][i] for i, f in enumerate(fruit_data.Fruit.unique())}

# color assignment for a large number of variables:
n_colors = len(fruit_data.Fruit.unique())
colorscale = colors = px.colors.sample_colorscale("viridis", [n/(n_colors -1) for n in range(n_colors)])
colordict = {f:colorscale[i] for i, f in enumerate(fruit_data.Fruit.unique())}

# plotly figure
fig = px.bar(
        fruit_data,
        x="Day",
        y="Value",
        color = 'Fruit',
        color_discrete_map = colordict
      )
fig.show()