Python/Matplotlib 子图 - 堆叠条形图 - 为类别设置固定颜色
Python/Matplotlib sub-plots - stacked bar plots - set fixed color for categories
我想从 pandas df(使用 df.pivot_table)创建堆叠条形图的子图,并使子图的类别颜色保持一致(即固定)。
问题是并非主元 table 中的每个索引值(样本 df 中的 'domain')都具有相同数量的类别 - 因此 matplotlib 重新启动每个子类别中的类别着色-plot - 导致相同的颜色被用于两个不同的类别。
这是用于说明的虚拟代码:
df:
main domain category val
0 cat1 a apple 1
1 cat1 a orange 1
2 cat1 a broccli 1
3 cat1 b apple 1
4 cat1 b orange 1
5 cat1 a plum 1
6 cat1 c apple 1
7 cat2 b orange 1
8 cat2 b orange 1
9 cat2 b apple 1
10 cat2 b orange 1
11 cat2 c plum 1
12 cat2 c apple 1
13 cat2 b orange 1
14 cat2 b orange 1
代码是:
import pandas as pd
import matplotlib.pyplot as plt
fig = plt.figure(figsize=(15, 10))
sub_plot_grid = (4, 10)
sub_plot_col_size = 5
sub_plot_row_size = 3
ax1 = plt.subplot2grid(sub_plot_grid, (0, 0), colspan=sub_plot_col_size, rowspan=sub_plot_row_size)
ax2 = plt.subplot2grid(sub_plot_grid, (0, 5), colspan=sub_plot_col_size, rowspan=sub_plot_row_size, sharey=ax1, sharex=ax1)
ax2.tick_params(axis='y', which='both', length=0)
list_of_ax = [ax1, ax2]
sub_df_1 = df[df['main'] == 'cat1']
sub_df_2 = df[df['main'] == 'cat2']
list_of_df = [sub_df_1, sub_df_2]
for ax, df in zip(list_of_ax, list_of_df):
df1 = df.pivot_table(index='domain', columns='category', values='val', aggfunc='sum', dropna=False, margins=True).sort_values(by='All', ascending=False).drop('All').drop('All', axis=1)
df1.drop(df1.loc[df1.sum(axis=1) == 0].index, inplace=True)
df1.drop(columns=df1.columns[df1.sum() == 0], inplace=True)
df1.plot(kind='barh', stacked=True, alpha=0.7, ax=ax)
plt.show()
剧情是:
问题在 'orange' 和 'plum' 类别中可见:在第一个子图中 - 'orange' 类别的颜色是绿色在第二个子图中颜色是橙色。 'plum' 第一个子图中的类别颜色为红色,第二个子图中的类别颜色为绿色。
我需要每个类别的颜色对于所有子图都保持相同。
我已经搜索了一段时间的解决方案并尝试了一些不同的方法,包括尝试手动传递颜色列表或使用颜色图,但是 matplotlib 重新启动每个子图的颜色的问题仍然存在。
如有任何帮助,我们将不胜感激。
请参阅 bar charts with pandas
的 color
参数的文档。具体来说,关于传递 dict
:
的部分
A dict of the form {column namecolor}, so that each column will be
colored accordingly. For example, if your columns are called a and b, then passing {‘a’: ‘green’, ‘b’: ‘red’} will color bars for column a in green and bars for column b in red.
所以如果你定义:
colors = {'apple':'red', 'orange':'orange', 'plum':'purple', 'broccli':'green'}
然后绘制:
df1.plot(kind='barh', stacked=True, alpha=0.7, ax=ax, color=colors)
您得到以下内容:
我想从 pandas df(使用 df.pivot_table)创建堆叠条形图的子图,并使子图的类别颜色保持一致(即固定)。
问题是并非主元 table 中的每个索引值(样本 df 中的 'domain')都具有相同数量的类别 - 因此 matplotlib 重新启动每个子类别中的类别着色-plot - 导致相同的颜色被用于两个不同的类别。
这是用于说明的虚拟代码:
df:
main domain category val
0 cat1 a apple 1
1 cat1 a orange 1
2 cat1 a broccli 1
3 cat1 b apple 1
4 cat1 b orange 1
5 cat1 a plum 1
6 cat1 c apple 1
7 cat2 b orange 1
8 cat2 b orange 1
9 cat2 b apple 1
10 cat2 b orange 1
11 cat2 c plum 1
12 cat2 c apple 1
13 cat2 b orange 1
14 cat2 b orange 1
代码是:
import pandas as pd
import matplotlib.pyplot as plt
fig = plt.figure(figsize=(15, 10))
sub_plot_grid = (4, 10)
sub_plot_col_size = 5
sub_plot_row_size = 3
ax1 = plt.subplot2grid(sub_plot_grid, (0, 0), colspan=sub_plot_col_size, rowspan=sub_plot_row_size)
ax2 = plt.subplot2grid(sub_plot_grid, (0, 5), colspan=sub_plot_col_size, rowspan=sub_plot_row_size, sharey=ax1, sharex=ax1)
ax2.tick_params(axis='y', which='both', length=0)
list_of_ax = [ax1, ax2]
sub_df_1 = df[df['main'] == 'cat1']
sub_df_2 = df[df['main'] == 'cat2']
list_of_df = [sub_df_1, sub_df_2]
for ax, df in zip(list_of_ax, list_of_df):
df1 = df.pivot_table(index='domain', columns='category', values='val', aggfunc='sum', dropna=False, margins=True).sort_values(by='All', ascending=False).drop('All').drop('All', axis=1)
df1.drop(df1.loc[df1.sum(axis=1) == 0].index, inplace=True)
df1.drop(columns=df1.columns[df1.sum() == 0], inplace=True)
df1.plot(kind='barh', stacked=True, alpha=0.7, ax=ax)
plt.show()
剧情是:
问题在 'orange' 和 'plum' 类别中可见:在第一个子图中 - 'orange' 类别的颜色是绿色在第二个子图中颜色是橙色。 'plum' 第一个子图中的类别颜色为红色,第二个子图中的类别颜色为绿色。
我需要每个类别的颜色对于所有子图都保持相同。
我已经搜索了一段时间的解决方案并尝试了一些不同的方法,包括尝试手动传递颜色列表或使用颜色图,但是 matplotlib 重新启动每个子图的颜色的问题仍然存在。
如有任何帮助,我们将不胜感激。
请参阅 bar charts with pandas
的 color
参数的文档。具体来说,关于传递 dict
:
A dict of the form {column namecolor}, so that each column will be colored accordingly. For example, if your columns are called a and b, then passing {‘a’: ‘green’, ‘b’: ‘red’} will color bars for column a in green and bars for column b in red.
所以如果你定义:
colors = {'apple':'red', 'orange':'orange', 'plum':'purple', 'broccli':'green'}
然后绘制:
df1.plot(kind='barh', stacked=True, alpha=0.7, ax=ax, color=colors)
您得到以下内容: