基于 pandas 数据框中两列的绘图中的颜色和透明度

问题描述 投票:0回答:1

我正在绘制一个堆叠+分组条形图。我对每个类别都有一个颜色字典,但我希望每个组都有不同的透明度来区分它们。

数据如下:

      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 以区分并排条。可以做吗?

python pandas plotly plotly-python
1个回答
0
投票

由于在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() 

© www.soinside.com 2019 - 2024. All rights reserved.