绘制元素不等的钢筋组

时间:2018-07-17 13:32:30

标签: python matplotlib

免责声明:也许我缺乏研究,但是我没有找到完全适合我的问题的答案。

我有一组具有特定大小的数据集,这些数据集在不同的年份提供。 例如,在2005年,我们有了数据集A(大小500),B(大小100)和C(大小789),然后在2013年有了数据集H(大小1500),I(大小300)和J(大小47)。

我想在垂直的YY轴上放置size,而水平XX轴则是分层的:首先由year进行排序,并在每年之内按size进行排序

此外,我想将XX标签显示为格式为“ YYYYdataset_name”的字符串。 对于上面的示例,XX轴将按以下顺序具有以下标签:

  

2005 B-100

     

2005年A-500

     

2005年C-789

     

2013 J-47

     

2013 I-300

     

2013 H-1500

从我发现的示例中,通常假定每个组中都存在相同的元素(如果是这种情况,每个数据集名称每年都会出现一次-但这不是我想要的)。

考虑来自The Python Graph Gallery的以下示例:

# libraries
import numpy as np
import matplotlib.pyplot as plt

# set width of bar
barWidth = 0.25

# set height of bar
bars1 = [12, 30, 1, 8, 22]
bars2 = [28, 6, 16, 5, 10]
bars3 = [29, 3, 24, 25, 17]

# Set position of bar on X axis
r1 = np.arange(len(bars1))
r2 = [x + barWidth for x in r1]
r3 = [x + barWidth for x in r2]

# Make the plot
plt.bar(r1, bars1, color='#7f6d5f', width=barWidth, edgecolor='white', label='var1')
plt.bar(r2, bars2, color='#557f2d', width=barWidth, edgecolor='white', label='var2')
plt.bar(r3, bars3, color='#2d7f5e', width=barWidth, edgecolor='white', label='var3')

# Add xticks on the middle of the group bars
plt.xlabel('group', fontweight='bold')
plt.xticks([r + barWidth for r in range(len(bars1))], ['A', 'B', 'C', 'D', 'E'])

# Create legend & Show graphic
plt.legend()
plt.show()

它产生以下图:

enter image description here

我的情节就是这样。 但是,并非所有变量都在每个类别中。 看起来像这样:

enter image description here

年份将出现在单个粗体字母所在的位置。 这些年来的文字不一定是数字,而可能是数据集名称。

但是,我需要将组等距隔开,如图所示。

任何帮助表示赞赏。

1 个答案:

答案 0 :(得分:0)

我实际上在一段时间之前解决了问题,但是直到现在我才发布解决方案。 本质上,我使用了另一个StackOverflow用户的方法来进行层次条形图绘制:

def mk_groups(data: Dict) -> List:
    try:
        newdata = data.items()
    except:
        return

    thisgroup = []
    groups = []
    for key, value in newdata:
        newgroups = mk_groups(value)
        if newgroups is None:
            thisgroup.append((key, value))
        else:
            thisgroup.append((key, len(newgroups[-1])))
            if groups:
                groups = [g + n for n, g in zip(newgroups, groups)]
            else:
                groups = newgroups
    ret_val = [thisgroup] + groups

    return ret_val

def add_line(ax, xpos: float, ypos: float) -> None:
    line = plt.Line2D([xpos, xpos], [ypos + .1, ypos],
                      transform=ax.transAxes, color='black')
    line.set_clip_on(False)
    ax.add_line(line)

def get_hirarchy_element_count(data: Dict) -> int:
    acc = 0
    for _, val in data.items():
        if isinstance(val, collections.Mapping):
            sub_groug_count = get_hirarchy_element_count(val)
            acc = acc + sub_groug_count
        else:
            acc = acc + 1
    return acc

def get_group_color_list(data: Dict, colors: List) -> List:
    acc = 0
    ind = 0
    new_colors = []
    for _, val in data.items():
        if isinstance(val, collections.Mapping):
            sub_groug_count = get_hirarchy_element_count(val)
            new_colors = new_colors + [colors[ind]] * sub_groug_count
            ind = ind + 1
        else:
            acc = acc + 1
    return new_colors

使用这些功能,您可以简单地定义字典词典,然后像这样调用这些功能:

plot_map = {
    2004: {'dataset A': 50,'dataset B': 30,'dataset C': 70,'dataset ZZZ': 10,},
    2007: {'dataset 111': 80,'dataset B3': 5},
    2010: {'dataset solitude': 40},
    2015: {
        'Group A': {'x' : 40, 'y': 60}, 
        'Group B': {'x' : 45, 'y': 45}
    }
}

fig = plt.figure(figsize=(12, 6))
plt.suptitle('Each group with its own color')
ax = fig.add_subplot(1,1,1)

label_group_bar(ax, plot_map, per_group_coloring = True)
fig.subplots_adjust(bottom=0.3)
plt.xticks(rotation=90)
plt.ylabel("Yet another scale")

plt.show()

这将产生一个图形,其中每组条形都有其自己的颜色:

enter image description here

但是,如果您希望每个条都有自己的颜色,则可以执行以下操作:

fig = plt.figure(figsize=(12, 6))
plt.suptitle('Each bar with its own color')
ax = fig.add_subplot(1,1,1)

label_group_bar(ax, plot_map)
fig.subplots_adjust(bottom=0.3)
plt.xticks(rotation=90)
plt.ylabel("Yet another scale")

plt.show()

enter image description here

我希望这对其他人有用。