Matplot表,图例,堆积的条形图问题

时间:2017-02-23 13:42:36

标签: python matplotlib

我正在处理堆积的条形图,正如您所看到的,它有一些问题: enter image description here 1)如何在表格中添加alpha?我尝试在alpha=0.75中添加the_table,但它没有做任何事情 2)如何增加表格行的高度以适应文本?
3)如何移动'3/1'条使其位于表格列的中心?
4)如何移动图例使其位于图形的中心?
5)如何修复被截断的图例?

这是我的代码:

import matplotlib.pyplot as plt
import numpy as np

res = (0, 21)
canc = (21, 0)
me = (37, 37)
ee = (4, 4)
sw = (16, 16)
te = (31, 31)
spec = (1, 1)
sys = (2, 2)
lm = (9, 9)

data = [res, canc, me, ee, sw, te, spec, sys, lm]
labels = ['Resolved', 'To be cancelled', 'Mech Eng', 'Elec Eng', 'Software', 'Test Eng', 'Specialty', 'Systems', 'LM Review']
dates = ('2/22', '3/1 (Projected)')

fig, ax = plt.subplots()

index = np.arange(len(dates))
bar_width = 0.25
y_offset = np.array([0.0] * len(dates))

gray = plt.cm.gray(0.5)
yellow = plt.cm.hot(0.9)
green = plt.cm.Greens(0.5)
magenta = plt.cm.RdPu(0.5)
orange = plt.cm.Oranges(0.5)
purple = plt.cm.Purples(0.5)
greenblue = plt.cm.GnBu(0.4)
red = plt.cm.Reds(0.5)
blue = plt.cm.Blues(0.5)
colors = [gray, yellow, green, magenta, orange, purple, greenblue, red, blue]

cell_text = []
for row in range(len(data)):
    plt.bar(index, data[row], bar_width, bottom=y_offset, color=colors[row], alpha=0.75, align='center', label=labels[row])
    y_offset = y_offset + data[row]

colors = colors[::-1]
data.reverse()
labels.reverse()

the_table = plt.table(cellText=data, rowLabels=labels, rowColours=colors, alpha=0.1, colLabels=dates, loc='bottom', cellLoc='center')
the_table.scale(1, 1.6)

plt.ylabel('Open Items')

plt.subplots_adjust(left=0.2, bottom=0.35)

plt.xticks([])
plt.yticks(np.arange(0, 130, 5))
ax.set_xlim(-0.5, 1.5)
plt.legend()

handles, labels = ax.get_legend_handles_labels()
ax.legend(handles[::-1], labels[::-1], bbox_to_anchor=(1., 1.15), ncol=4)

plt.show()
编辑:发现:
解决方案#2& #3。
#1的解决方法,但仍然希望能够实际应用alpha而不是操纵颜色 得到了我想要的传奇,但现在它被切断了。

1 个答案:

答案 0 :(得分:1)

1)添加alpha:您可以使用相应颜色的Alpha通道。这是通过将颜色转换为rgba然后将元组的alpha设置为所需的值来完成的。

alpha = 0.75
colors = ['gray', 'yellow', 'green']
cols=[]
for c in colors:
    col = list(matplotlib.colors.to_rgba(c))
    col[3] = alpha
    cols.append(col)

2)图表上方的中心图例:这一点都取决于图形大小,字体大小等,所以理想的参数需要通过反复试验找到,但想法可以是放置边界框的轴中心的图例(x = 0.5)及其顶部(y = 1.0)并指定loc参数为'lower center',这意味着图例的底部中心应位于点。使y稍大一些会在图例和轴之间产生一些填充。

这是完整的脚本,我还调整了图形大小,让所有图形都适合画布。

import matplotlib.pyplot as plt
import numpy as np
import matplotlib.colors

res = (0, 21)
canc = (21, 0)
me = (37, 37)
ee = (4, 4)
sw = (16, 16)
te = (31, 31)
spec = (1, 1)
sys = (2, 2)
lm = (9, 9)

data = [res, canc, me, ee, sw, te, spec, sys, lm]
labels = ['Resolved', 'To be cancelled', 'Mech Eng', 'Elec Eng', 'Software', 'Test Eng', 'Specialty', 'Systems', 'LM Review']
dates = ('2/22', '3/1 (Projected)')

fig, ax = plt.subplots(figsize=(6,6)) #<- set figure size large enough for data

index = np.arange(len(dates))
bar_width = 0.25
y_offset = np.array([0.0] * len(dates))

# set alpha to colors:
alpha = 0.75
colors = ['gray', 'yellow', 'green', 'magenta', 'orange', 'palevioletred', 'mediumspringgreen', 'red', 'blue']
cols=[]
for c in colors:
    col = list(matplotlib.colors.to_rgba(c))
    col[3] = alpha
    cols.append(col)
colors = cols[::-1]

cell_text = []
for row in range(len(data)):                              #colors need to be inverted here as well, don't they?
    plt.bar(index, data[row], bar_width, bottom=y_offset, color=colors[::-1][row], alpha=0.75, align='center', label=labels[row])
    y_offset = y_offset + data[row]


data.reverse()
labels.reverse()

the_table = plt.table(cellText=data, rowLabels=labels, rowColours=colors, alpha=0.1, colLabels=dates, loc='bottom', cellLoc='center')
the_table.scale(1, 1.6)

plt.ylabel('Open Items')

plt.subplots_adjust(left=0.22, bottom=0.35, right=0.78, top=0.82) # <- allocate some spacing for legend on top and on right as well

plt.xticks([])
plt.yticks(np.arange(0, 130, 5))
ax.set_xlim(-0.5, 1.5)
#plt.legend() <- remove, we only need one single legend defined below

handles, labels = ax.get_legend_handles_labels()
# loc=8 means the bbox ccordinates define the lower center of the legend
# so placing it at x=0.5 ( horizontal center of the axes), y=1.02 (vertical top of the axes)
ax.legend(handles[::-1], labels[::-1], loc=8, bbox_to_anchor=(0.5, 1.02), ncol=4)

plt.show()

enter image description here