在matplotlib中设置分组条形图之间的间距 [英] setting spacing between grouped bar plots in matplotlib

查看:2415
本文介绍了在matplotlib中设置分组条形图之间的间距的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图按照图库中的示例在matplotlib中进行分组的条形图.我使用以下内容:

I'm trying to make a grouped bar plot in matplotlib, following the example in the gallery. I use the following:

import matplotlib.pyplot as plt
plt.figure(figsize=(7,7), dpi=300)
xticks = [0.1, 1.1]
groups = [[1.04, 0.96],
          [1.69, 4.02]]
group_labels = ["G1", "G2"]
num_items = len(group_labels)
ind = arange(num_items)
width = 0.1
s = plt.subplot(1,1,1)
for num, vals in enumerate(groups):
    print "plotting: ", vals
    group_len = len(vals)
    gene_rects = plt.bar(ind, vals, width,
                         align="center")
    ind = ind + width
num_groups = len(group_labels)
# Make label centered with respect to group of bars
# Is there a less complicated way?
offset = (num_groups / 2.) * width
xticks = arange(num_groups) + offset
s.set_xticks(xticks)
print "xticks: ", xticks
plt.xlim([0 - width, max(xticks) + (num_groups * width)])
s.set_xticklabels(group_labels)

我的问题是:

  1. 如何控制条形组之间的间距?现在,间隔很大,看起来很傻.请注意,我不想使这些条变得更宽-我希望它们具有相同的宽度,但要靠得更近些.

  1. How can I control the space between the groups of bars? Right now the spacing is huge and it looks silly. Note that I do not want to make the bars wider - I want them to have the same width, but be closer together.

如何使标签在条形图的下方居中?我试图进行一些算术计算,以将xlabels定位在正确的位置(请参见上面的代码),但它仍然略有偏离...感觉有点像编写绘图库而不是使用它.如何解决? (是否有matplotlib的包装器或内置实用程序,这是默认行为?)

How can I get the labels to be centered below the groups of bars? I tried to come up with some arithmetic calculations to position the xlabels in the right place (see code above) but it's still slightly off... it feels a bit like writing a plotting library rather than using one. How can this be fixed? (Is there a wrapper or built in utility for matplotlib where this is default behavior?)

编辑:回复@mlgill:谢谢您的回答.您的代码当然要优雅得多,但仍然存在相同的问题,即条的宽度和组之间的间距不是分开控制的.您的图形看起来正确,但是条形太宽了-它看起来像Excel图形-我想使条形变细.

Reply to @mlgill: thank you for your answer. Your code is certainly much more elegant but still has the same issue, namely that the width of the bars and the spacing between the groups are not controlled separately. Your graph looks correct but the bars are far too wide -- it looks like an Excel graph -- and I wanted to make the bar thinner.

宽度和边距现在已链接,因此,如果我尝试:

Width and margin are now linked, so if I try:

margin = 0.60
width = (1.-2.*margin)/num_items

它使条形更窄,但使组之间的距离变远,因此该图再次看起来不正确.

It makes the bar skinnier, but brings the group far apart, so the plot again does not look right.

如何制作具有两个参数的分组条形图函数:每个条形的宽度和条形组之间的间距,并像代码一样正确地绘制它,即x轴标签居中组?

How can I make a grouped bar plot function that takes two parameters: the width of each bar, and the spacing between the bar groups, and plots it correctly like your code did, i.e. with the x-axis labels centered below the groups?

我认为,由于用户必须计算特定的底层布局量(例如边距和宽度),因此我们基本上仍在编写绘图库:)

I think that since the user has to compute specific low-level layout quantities like margin and width, we are still basically writing a plotting library :)

推荐答案

解决这两个问题的技巧是了解Matplotlib中的条形图期望每个系列(G1,G2)的总宽度为"1.0"(计算)两侧的边距.因此,最可能的方法是设置边距,然后根据每个系列有多少条边来计算每个条的宽度.在您的情况下,每个系列有两个小节.

The trick to both of your questions is understanding that bar graphs in Matplotlib expect each series (G1, G2) to have a total width of "1.0", counting margins on either side. Thus, it's probably easiest to set margins up and then calculate the width of each bar depending on how many of them there are per series. In your case, there are two bars per series.

假设您左对齐每个条形,而不是像以前那样将它们居中对齐,则此设置将产生在x轴上范围从0.0到1.0、1.0到2.0等的序列.因此,每个系列的确切中心(即您希望标签出现的中心)将位于0.5、1.5等处.

Assuming you left align each bar, instead of center aligning them as you had done, this setup will result in series which span from 0.0 to 1.0, 1.0 to 2.0, and so forth on the x-axis. Thus, the exact center of each series, which is where you want your labels to appear, will be at 0.5, 1.5, etc.

我清理了您的代码,因为有很多无关的变量.查看其中的评论.

I've cleaned up your code as there were a lot of extraneous variables. See comments within.

import matplotlib.pyplot as plt
import numpy as np

plt.figure(figsize=(7,7), dpi=300)

groups = [[1.04, 0.96],
          [1.69, 4.02]]
group_labels = ["G1", "G2"]
num_items = len(group_labels)
# This needs to be a numpy range for xdata calculations
# to work.
ind = np.arange(num_items)

# Bar graphs expect a total width of "1.0" per group
# Thus, you should make the sum of the two margins
# plus the sum of the width for each entry equal 1.0.
# One way of doing that is shown below. You can make
# The margins smaller if they're still too big.
margin = 0.05
width = (1.-2.*margin)/num_items

s = plt.subplot(1,1,1)
for num, vals in enumerate(groups):
    print "plotting: ", vals
    # The position of the xdata must be calculated for each of the two data series
    xdata = ind+margin+(num*width)
    # Removing the "align=center" feature will left align graphs, which is what
    # this method of calculating positions assumes
    gene_rects = plt.bar(xdata, vals, width)


# You should no longer need to manually set the plot limit since everything 
# is scaled to one.
# Also the ticks should be much simpler now that each group of bars extends from
# 0.0 to 1.0, 1.0 to 2.0, and so forth and, thus, are centered at 0.5, 1.5, etc.
s.set_xticks(ind+0.5)
s.set_xticklabels(group_labels)

这篇关于在matplotlib中设置分组条形图之间的间距的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆