我正在绘制一个堆叠+分组条形图。我对每个类别都有一个颜色字典,但我希望每个组都有不同的透明度来区分它们。
数据如下:
year subplot plot_label value
0 2019 Projected Category 1 3.1
1 2020 Projected Category 1 3.0
2 2021 Projected Category 1 2.8
3 2019 Projected Category 2 3.1
4 2020 Projected Category 2 3.0
5 2021 Projected Category 2 2.8
6 2019 Actual Category 1 3.1
7 2020 Actual Category 1 3.0
8 2021 Actual Category 1 2.8
9 2019 Actual Category 2 3.1
10 2020 Actual Category 2 3.0
11 2021 Actual Category 2 2.8
以及绘图代码:
colour_dict = {'Category 1': '#123', 'Category 2': '#456'}
fig = px.bar(df, x='subplot', y='value', facet_col='year', color='plot_label',
facet_col_spacing=0.01, color_discrete_map=colour_dict)
目前
Projected
和 Actual
条具有基于 plot_label
类别的相同配色方案,但我想添加更改其中一个的 alpha 以区分并排条。可以做吗?
由于在express中无法设置单独的透明度,因此必须由图形对象来处理。我根据为数据框的每个类别单元提取的数据设置了一个子图。我还设置了类别值的透明度。更改标记的颜色以区分透明度。图例现在是单个图例,因为由于图表是由数据行创建的,所以它是重复的。其余数据现在与 Express 中的显示方式一致。
import plotly.graph_objects as go
from plotly.subplots import make_subplots
#colour_dict = {'Category 1': '#123', 'Category 2': '#456'}
colour_dict = {'Category 1': '#808080', 'Category 2': '#dc143c'}
fig = make_subplots(rows=1, cols=3, subplot_titles=[f'year={str(y)}' for y in [2019,2020,2021]])
for i,y in enumerate(df['year'].unique()):
dfy = df.query('year == @y')
for c in dfy['plot_label'].unique():
dfc = dfy.query('plot_label == @c')
for s in dfc['subplot'].unique():
dfs = dfc.query('subplot == @s')
opacity = 0.5 if dfs['subplot'].values[0] == 'Actual' else 1.0
color = colour_dict['Category 2'] if dfs['plot_label'].values[0] == 'Category 2' else colour_dict['Category 1']
fig.add_trace(go.Bar(
x=dfs['subplot'],
y=dfs['value'],
marker=dict(color=color,
opacity=opacity
),
name=c,
), row=1, col=i+1)
# Remove duplicate legends
names = set()
fig.for_each_trace(
lambda trace:
trace.update(showlegend=False)
if (trace.name in names) else names.add(trace.name))
fig.update_layout(barmode='stack')
fig.update_layout(xaxis2_title='subplot', yaxis_title='value')
fig.update_layout(legend_traceorder="normal")
fig.show()