matplotlib 添加图例海运条形图

68bkxrlz  于 2023-06-23  发布在  其他
关注(0)|答案(2)|浏览(105)
import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt

array = np.array([[1,5,9],[3,5,7]])

df = pd.DataFrame(data=array, index=['Positive', 'Negative'])

f, ax = plt.subplots(figsize=(8, 6))

current_palette = sns.color_palette('colorblind')

ax_pos = sns.barplot(x = np.arange(0,3,1), y = df.loc['Positive'].to_numpy(), color = current_palette[2], alpha = 0.66)
ax_neg = sns.barplot(x = np.arange(0,3,1), y = df.loc['Negative'].to_numpy(), color = current_palette[4], alpha = 0.66)

plt.xticks(np.arange(0,3,1), fontsize = 20)
plt.yticks(np.arange(0,10,1), fontsize = 20)

plt.legend((ax_pos[0], ax_neg[0]), ('Positive', 'Negative'))

plt.tight_layout()

这将产生以下错误:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[32], line 15
     12 plt.xticks(np.arange(0,3,1), fontsize = 20)
     13 plt.yticks(np.arange(0,10,1), fontsize = 20)
---> 15 plt.legend((ax_pos[0], ax_neg[0]), ('Positive', 'Negative'))
     17 plt.tight_layout()

TypeError: 'Axes' object is not subscriptable

我想知道为什么seaborn不能这样调用legend(plt.legend(ax[0]...),而matplotlib可以。
最后,我只想要左上角的图例。

yzxexxkh

yzxexxkh1#

我发现条形图有“标签”功能:

import numpy as np
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt

array = np.array([[1,5,9],[3,5,7]])

df = pd.DataFrame(data=array, index=['Positive', 'Negative'])

f, ax = plt.subplots(figsize=(8, 6))

current_palette = sns.color_palette('colorblind')

sns.barplot(x = np.arange(0,3,1), y = df.loc['Positive'].to_numpy(), color = current_palette[2], alpha = 0.66, label = "Positive")
sns.barplot(x = np.arange(0,3,1), y = df.loc['Negative'].to_numpy(), color = current_palette[4], alpha = 0.66, label = "Negative")

plt.xticks(np.arange(0,3,1), fontsize = 20)
plt.yticks(np.arange(0,10,1), fontsize = 20)

plt.legend(frameon = False)

plt.tight_layout()

ygya80vv

ygya80vv2#

  • OP中的条形图和其他answer是错误的。条形图按z顺序分层,而不是堆叠,这是不标准的,并且可能被误解。如图plot所示。
  • 绘制一个宽 Dataframe 的正确方法是使用pandas.DataFrame.plot
  • index中的值将是xticklabelscolumn名称将是图例标签。
  • 根据数据的呈现方式,使用.T转置indexcolumns
  • 一般来说,堆叠条形图并不是呈现数据的最佳方式,因为在两组之外,很难准确地比较长度。
  • 分组条更好,因为条的长度更容易比较。
  • 正如这个答案所示,最好正确使用seabornpandas的绘图API来管理图例。
  • pandas使用matplotlib作为默认绘图后端,seabornmatplotlib的高级API。
  • 在本例中,df已经具有用于图例的标签。
  • 如果数据框没有合适的标签,最好是管理、转换和清理数据框,让绘图API处理图例、标签等。
  • 使用.rename重命名列和索引值。
  • 使用.map添加一个新列,用于seaborn中的hue
  • 请参阅Move seaborn plot legend to a different positionHow to put the legend outside the plot以全面了解移动图例选项。
    *python 3.11.3pandas 2.0.2matplotlib 3.7.1seaborn 0.12.2中测试
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt

# sample wide dataframe
df = pd.DataFrame(data=np.array([[1, 5, 9],[3, 5, 7]]),
                  index=['Positive', 'Negative'])

# covert to long form
dfm = df.melt(ignore_index=False).reset_index(names='Cat')

叠棒pandas.DataFrame.plot

  • 这需要一行代码来实现。
# transpose and plot the dataframe
ax = df.T.plot(kind='bar', stacked=True, rot=0, figsize=(8, 6))

# cosmetics
ax.spines[['top', 'right']].set_visible(False)
ax.legend(title='Cat', bbox_to_anchor=(1, 0.5), loc='center left', frameon=False)

  • 使用stacked=False,这是更好的选择。

seaborn.histplot的叠棒

  • seaborn最适合长格式的数据,因此使用dfm
  • sns.barplot不做堆叠棒,所以必须使用sns.histplot
  • histplot用于显示连续数据的分布,由于传递给x-axis的列是数字,因此轴显示为连续的,而不是离散的类别。
fig, ax = plt.subplots(figsize=(8, 6))
sns.histplot(data=dfm, x='variable', weights='value', hue='Cat', multiple='stack', discrete=True, ax=ax)

# cosmetics
ax.spines[['top', 'right']].set_visible(False)
sns.move_legend(ax, bbox_to_anchor=(1, 0.5), loc='center left', frameon=False)

seaborn.barplot成组钢筋

fig, ax = plt.subplots(figsize=(8, 6))
sns.barplot(data=dfm, x='variable', y='value', hue='Cat', ax=ax)

# cosmetics
ax.spines[['top', 'right']].set_visible(False)
sns.move_legend(ax, bbox_to_anchor=(1, 0.5), loc='center left', frameon=False)

相关问题