Matplotlib极坐标条形图图例

1 投票
1 回答
4141 浏览
提问于 2025-04-18 17:33

我有一些问卷的数据,这些数据在6个“维度”上提供了答案(每个答案的值在0到4之间)。我想把这6个“维度”的平均值画成一个极坐标柱状图。

这是我的代码:

#!/usr/bin/env python3
import numpy as np
import matplotlib.pyplot as plt

data = np.array([2.83333333, 1.6, 1.75, 2.6, 0.875, 1.75])

N = len(data)
theta = np.linspace(0.0, 2 * np.pi, N, endpoint=False)
radii = data
width = 2 * np.pi / N

ax = plt.subplot(111, polar=True)

bars = ax.bar(theta, radii, width=width, bottom=0.0)
ax.yaxis.set_ticks([0,1,2,3,4])
ax.yaxis.set_ticklabels(['None','Mild','Moderate','Severe','Extreme'])
ax.xaxis.set_ticks(theta)
ax.xaxis.set_ticklabels([1,2,3,4,5,6])

ax.legend(['foo','bar','snafu','swag','s-fus','tarfu'])

for r, bar in zip(theta, bars):
    bar.set_facecolor(plt.cm.jet(r / np.pi / 2))
    bar.set_alpha(0.8)

plt.show()

运行后得到了这样的结果:

http://i60.tinypic.com/2rxaatc.png

我选择使用图例来给柱子命名,因为实际的描述会比较长,比如“理解和沟通”。另外一种方法是使用主要刻度之间的x轴标签(不过我对怎么做也没有好的主意,而且可能效果也不好)。

现在的问题是:为什么其他的图例不显示出来(我随机得到了第二个,但就只有这个)?

1 个回答

0

bars 是一个 Container 对象,里面包含了六个 matplotlib.patches.Rectangle,这些矩形构成了你的柱状图。默认情况下,legend() 会把它当作一个整体来处理,所以你只会看到一个图例项来表示所有的柱子。

你可以通过使用另一种语法来强制 legend() 为每个柱子绘制单独的图例项:

legend(sequence_of_artists, sequence_of_labels, ...)

试试这个:

ax.legend(bars, ['foo','bar','snafu','swag','s-fus','tarfu'])

在你改变柱子的颜色之后再创建图例,否则图例上的颜色和柱子的颜色就不匹配了。


还有一种方法可以达到同样的效果,那就是为每个柱子设置 label 属性,和你现在设置颜色的方式类似。当每个柱子都有自己的 label 时,legend() 会自动把它们当作独立的对象来处理,并为每个柱子绘制图例项。

...
labels = ['foo','bar','snafu','swag','s-fus','tarfu']
for r, bar, ll in zip(theta, bars, labels):
    bar.set_facecolor(plt.cm.jet(r / np.pi / 2))
    bar.set_alpha(0.8)
    bar.set_label(ll)

ax.legend()
...

撰写回答