【问题标题】:Matplot table, legend, stacked barplot issuesMatplot 表格、图例、堆积条形图问题
【发布时间】:2017-02-24 00:19:13
【问题描述】:

我正在处理堆积条形图,如您所见,它存在一些问题: 1)如何在表格中的颜色中添加 alpha?我尝试在the_table 中添加alpha=0.75,但它没有做任何事情。
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 而不是操纵颜色。
得到了我想要的图例,但现在它被切断了。

【问题讨论】:

    标签: python matplotlib


    【解决方案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()
    

    【讨论】:

    • 谢谢。我收到一个错误:AttributeError: 'module' object has no attribute 'to_rgba'。看起来我安装了 1.5 版,我猜 to_rgba 只是 2.0 版?
    • 可能是这样。 matplotlib.colors.colorConverter.to_rgba(c) 可以代替吗?
    • 它没有。正在尝试下载并安装 2.0。
    • 这很奇怪,根据the documentation,即使在matplotlib 1.4 中也有一个matplotlib.colors.ColorConverterto_rgba 方法。
    • 不知道为什么我会收到那个错误。但是安装 2.0 修复了它。再次感谢。
    猜你喜欢
    • 1970-01-01
    • 2019-06-19
    • 2021-07-03
    • 2016-06-29
    • 2019-04-17
    • 1970-01-01
    • 2017-05-27
    • 2017-04-30
    • 1970-01-01
    相关资源
    最近更新 更多