能否为Plotly堆叠柱状图添加颜色渐变?实现多维度颜色编码
问题描述
我有一个基于Plotly Express的堆叠柱状图,X轴是20种期刊名称,每个期刊内按Access(访问类型)分为堆叠分段,且访问类型数据涵盖多个年份。请问能否同时通过颜色编码Access类型和Year(年份)?若可行,希望为每种颜色添加渐变来表示年份。
最小可复现代码(MWE)
import pandas as pd import plotly.express as px d = {'Journal': ['Journal One', 'Journal One', 'Journal One', 'Journal One', 'Journal One', 'Journal One', 'Journal One'], 'Access': ['Green', 'Green', 'Closed', 'Green', 'Closed', 'Green', 'Closed'], 'Year': [2020, 2021, 2021, 2022, 2022, 2023, 2023], 'Count': [1, 1, 5, 6, 3, 2, 4]} df = pd.DataFrame(data=d) fig = px.bar(df, x='Journal', y='Count', color='Access', text_auto=True, category_orders={'Access': ["Closed", "Green"]}, color_discrete_map={ "Closed": "#AB63FA", "Green": "#2CA02C"}, title = f'Journal Titles by Access status and Year' ) fig.show()
请问我能否按Year为绿色和紫色指定渐变或透明度级别,以区分颜色块内的不同数据?是否可以添加两种颜色编码?或者有更优的展示方式?
解决方案
1. 给同一Access类型的不同年份添加颜色渐变/透明度
可以通过结合Access和Year生成新的分类字段,然后为每个分类设置深浅渐变的颜色,或者调整透明度来区分年份。
方法一:自定义渐变颜色映射
为每个Access类型定义颜色渐变范围,根据年份映射对应颜色:
import pandas as pd import plotly.express as px from plotly.colors import sample_colorscale # 定义颜色渐变:年份越晚,颜色越深 closed_colors = sample_colorscale('purples', [0.3, 0.5, 0.7, 0.9]) green_colors = sample_colorscale('greens', [0.3, 0.5, 0.7, 0.9]) d = {'Journal': ['Journal One', 'Journal One', 'Journal One', 'Journal One', 'Journal One', 'Journal One', 'Journal One'], 'Access': ['Green', 'Green', 'Closed', 'Green', 'Closed', 'Green', 'Closed'], 'Year': [2020, 2021, 2021, 2022, 2022, 2023, 2023], 'Count': [1, 1, 5, 6, 3, 2, 4]} df = pd.DataFrame(data=d) # 生成Access+Year的组合字段 df['Access_Year'] = df['Access'] + '_' + df['Year'].astype(str) # 构建颜色映射表 year_order = sorted(df['Year'].unique()) color_map = {} for i, year in enumerate(year_order): color_map[f'Closed_{year}'] = closed_colors[i] color_map[f'Green_{year}'] = green_colors[i] fig = px.bar(df, x='Journal', y='Count', color='Access_Year', text_auto=True, category_orders={ 'Access_Year': [f'{access}_{year}' for access in ["Closed", "Green"] for year in year_order] }, color_discrete_map=color_map, title='期刊按访问类型和年份统计' ) # 调整图例分组,提升可读性 fig.update_layout( legend=dict( tracegroupgap=20, itemsizing='constant' ) ) fig.show()
方法二:通过透明度区分年份
固定Access的基础颜色,仅按年份调整透明度(年份越晚透明度越高):
import pandas as pd import plotly.express as px d = {'Journal': ['Journal One', 'Journal One', 'Journal One', 'Journal One', 'Journal One', 'Journal One', 'Journal One'], 'Access': ['Green', 'Green', 'Closed', 'Green', 'Closed', 'Green', 'Closed'], 'Year': [2020, 2021, 2021, 2022, 2022, 2023, 2023], 'Count': [1, 1, 5, 6, 3, 2, 4]} df = pd.DataFrame(data=d) # 生成Access+Year的组合字段 df['Access_Year'] = df['Access'] + '_' + df['Year'].astype(str) # 定义基础颜色,按年份调整透明度 base_colors = {"Closed": "#AB63FA", "Green": "#2CA02C"} year_order = sorted(df['Year'].unique()) color_map = {} for year in year_order: alpha = 0.5 + (year - min(year_order))/(max(year_order)-min(year_order))*0.4 # 透明度范围0.5-0.9 for access in ["Closed", "Green"]: # 十六进制转RGBA格式 hex_color = base_colors[access] r = int(hex_color[1:3], 16) g = int(hex_color[3:5], 16) b = int(hex_color[5:7], 16) color_map[f'{access}_{year}'] = f'rgba({r}, {g}, {b}, {alpha})' fig = px.bar(df, x='Journal', y='Count', color='Access_Year', text_auto=True, category_orders={ 'Access_Year': [f'{access}_{year}' for access in ["Closed", "Green"] for year in year_order] }, color_discrete_map=color_map, title='期刊按访问类型和年份统计(透明度区分年份)' ) fig.update_layout(legend=dict(tracegroupgap=20)) fig.show()
2. 更优的展示方式
如果堆叠渐变的可读性不足,可考虑以下方案:
- 分面柱状图:按年份分面展示,每个年份单独呈现所有期刊的Access堆叠数据,年份对比更清晰:
fig = px.bar(df, x='Journal', y='Count', color='Access', text_auto=True, facet_col='Year', facet_col_wrap=2, category_orders={'Access': ["Closed", "Green"]}, color_discrete_map={"Closed": "#AB63FA", "Green": "#2CA02C"}, title='期刊按访问类型统计(分年份展示)' ) fig.show() - 分组柱状图:将同一期刊的不同年份数据并列展示,而非堆叠,适合对比同一期刊跨年份的Access数据变化:
fig = px.bar(df, x='Journal', y='Count', color='Access', text_auto=True, barmode='group', facet_col='Year', facet_col_wrap=2, category_orders={'Access': ["Closed", "Green"]}, color_discrete_map={"Closed": "#AB63FA", "Green": "#2CA02C"}, title='期刊按访问类型统计(分组展示年份)' ) fig.show()
内容的提问来源于stack exchange,提问作者eschares
相关产品推荐
相关产品推荐

