python 两个子图之间的颜色不匹配&图例顺序

k97glaaz  于 2023-04-28  发布在  Python
关注(0)|答案(3)|浏览(167)

我正在与我的Seaborn箱线图和直方图(绘制为子图)的两个小格式问题作斗争。
1.两个子图之间的颜色是 * 略有 * 不同,即使编码的颜色是完全相同的。
1.我正试着重新排列图例的顺序,使'A组'出现在'B组'的上面

groupA = [94, 74, 65, 36, 32, 65, 56, 59, 24, 133, 16, 8, 18]
groupB = [1, 1, 1, 1, 2, 7, 7, 10, 15, 16, 17, 17, 19, 29, 31, 32, 43, 43, 44, 47, 56, 64, 64, 80, 81, 87, 103, 121, 121, 121, 187, 197, 236, 292, 319, 8, 12, 12, 14, 14, 15, 16, 16, 20, 20, 33, 36, 37, 37, 44, 46, 48, 51, 51, 54, 57, 72, 74, 95, 103, 103, 107, 134, 199, 216, 228, 254]
f, (ax_boxplot, ax_histogram) = plt.subplots(2, sharex=True, gridspec_kw={'height_ratios': (0.3,0.7)}, figsize=(10,10))
sns.boxplot(data=[groupA, groupB], ax=ax_boxplot, orient='h', palette=['green', 'silver'])
ax_boxplot.tick_params(axis='y', left=False, labelleft=False)
sns.histplot(data=[groupA, groupB], bins=34, binrange=(0,340), palette=['green', 'silver'], alpha=1, edgecolor='black')
ax_histogram.tick_params(axis='both', labelsize=18)
ax_histogram.legend(labels=['groupB', 'groupA'], fontsize=16, frameon=False)
plt.xlabel("Days", fontsize=24, labelpad=20)
plt.ylabel("Count", fontsize=24, labelpad=20)
sns.despine()

到目前为止我所尝试的:

  • 颜色:我试着在直方图中将alpha设置为1,但似乎仍然有轻微的差异。
  • 对于图例:尝试使用hue_order和handles,但没有任何成功的机会。

0x6upsns

0x6upsns1#

尝试在调用boxplot时使用saturation=1。除非另有说明,否则饱和度等于0.75
该文档说:
饱和浮动,可选
绘制颜色的原始饱和度的比例。大色块使用稍微不饱和的颜色通常会看起来更好,但如果希望打印颜色与输入颜色完全匹配,请将该值设置为1。

fiei3ece

fiei3ece2#

您的着色问题通常出现在StackOverflow上。例如Avoid Seaborn barplot desaturation of colorsSeaborn chart colors are different from those specified by paletteInconsistent colours from custom seaborn palette。Seaborn的作者喜欢矩形的去饱和颜色,所以默认情况下启用了这一功能。
Seaborn创建了自己的图例,通常与调用matplotlib的ax.legend(...)得到的图例不同。要更改图例的参数,Seaborn有一个sns.move_legend()函数。move_legend主要用于更改位置,但您也可以更改其他参数(项目标签除外)。由于“new”位置是一个必需参数,因此可以使用默认值loc='best'
对于图例中的标签,Seaborn的常用方法是“长格式” Dataframe ,其中一列用作hue=。但是Seaborn也支持字典data。然后,字典的标签用作图例标签。
请注意,除非添加sns.histplot(..., multiple='stack')(或multiple='dodge'),否则最后绘制的直方图的条形将隐藏(部分或全部)其他直方图的条形。这可能非常令人困惑(这就是为什么默认设置了一些透明度)。

import matplotlib.pyplot as plt
import seaborn as sns

groupA = [94, 74, 65, 36, 32, 65, 56, 59, 24, 133, 16, 8, 18]
groupB = [1, 1, 1, 1, 2, 7, 7, 10, 15, 16, 17, 17, 19, 29, 31, 32, 43, 43, 44, 47, 56, 64, 64, 80, 81, 87, 103, 121, 121, 121, 187, 197, 236, 292, 319, 8, 12, 12, 14, 14, 15, 16, 16, 20, 20, 33, 36, 37, 37, 44, 46, 48, 51, 51, 54, 57, 72, 74, 95, 103, 103, 107, 134, 199, 216, 228, 254]
f, (ax_boxplot, ax_histogram) = plt.subplots(2, sharex=True,
                                             gridspec_kw={'height_ratios': (0.3, 0.7)}, figsize=(10, 10))

sns.boxplot(data=[groupA, groupB], ax=ax_boxplot, orient='h',
            palette=['green', 'silver'], saturation=1)
ax_boxplot.tick_params(axis='y', left=False, labelleft=False)

sns.histplot(data={'Group A': groupA, 'Group B': groupB},
             bins=34, binrange=(0, 340),
             palette=['green', 'silver'], alpha=1, edgecolor='black')
ax_histogram.tick_params(axis='both', labelsize=18)
ax_histogram.set_xlabel("Days", fontsize=24, labelpad=20)
ax_histogram.set_ylabel("Count", fontsize=24, labelpad=20)
sns.move_legend(ax_histogram, loc='best', fontsize=24, frameon=False)
sns.despine()

plt.show()

6mw9ycah

6mw9ycah3#

  • 正如@JohanC所提到的,将数据放入一个长格式的数据框架中的好处是允许seaborn自动添加标签,并处理顺序。
  • pd.DataFrame(data=v, columns=['Days']).assign(Group=group)用于为每个列表创建 Dataframe ,其中.assign为数据的名称创建一个名为'Group'的列。这两个 Dataframe 用pd.concat组合。
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt

# set the matplotlib rc parameters (global settting)
params = {'axes.labelsize': 24,
          'axes.titlesize': 24,
          'axes.labelpad': 20,
          'axes.spines.top': False,
          'axes.spines.right': False,
          'ytick.labelsize': 18,
          'xtick.labelsize': 18,
          'legend.fontsize': 20,
          'legend.frameon': False,
          'legend.title_fontsize': 16}

plt.rcParams.update(params)

# create the dataframe with a column defining the groups
df = pd.concat([pd.DataFrame(data=v, columns=['Days']).assign(Group=group) for v, group in zip([groupA, groupB], ['A', 'B'])])

# create the figure and axes
fig, (ax_boxplot, ax_histogram) = plt.subplots(2, sharex=True, gridspec_kw={'height_ratios': (0.3,0.7)}, figsize=(10,10))

# plot the histplot from df
sns.histplot(data=df, x='Days', hue='Group', bins=34, binrange=(0,340), palette=['green', 'silver'], alpha=1, edgecolor='black', ax=ax_histogram)

# plot the boxplot from df
sns.boxplot(data=df, x='Days', y='Group', ax=ax_boxplot, palette=['green', 'silver'])
ax_boxplot.tick_params(axis='y', left=False, labelleft=False, bottom=False)
_ = ax_boxplot.set(xlabel='', ylabel='')

df.head(15)

Days Group
0     94     A
1     74     A
2     65     A
3     36     A
4     32     A
5     65     A
6     56     A
7     59     A
8     24     A
9    133     A
10    16     A
11     8     A
12    18     A
0      1     B
1      1     B

相关问题