Python 在matplotlib中设置分组条形图之间的间距
我正试图在matplotlib中创建一个分组条形图,如下图库中的示例所示。我使用以下方法:Python 在matplotlib中设置分组条形图之间的间距,python,numpy,plot,matplotlib,scipy,Python,Numpy,Plot,Matplotlib,Scipy,我正试图在matplotlib中创建一个分组条形图,如下图库中的示例所示。我使用以下方法: 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 = arang
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)
我的问题是:
margin = 0.60
width = (1.-2.*margin)/num_items
这会使酒吧更瘦,但会使团队相隔很远,因此情节看起来也不对
我如何制作一个分组条形图函数,该函数采用两个参数:每个条形图的宽度和条形图组之间的间距,并像代码那样正确地进行打印,即x轴标签位于组下方的中心
我认为,由于用户必须计算特定的低级布局数量,如边距和宽度,我们基本上仍在编写一个绘图库:)两个问题的诀窍是理解Matplotlib中的条形图期望每个系列(G1、G2)的总宽度为“1.0”,计算两侧的边距。因此,最简单的方法可能是设置边距,然后根据每个系列有多少边距来计算每个条的宽度。在您的情况下,每个系列有两个条 假设您左对齐每个条,而不是像之前那样将它们居中对齐,此设置将生成x轴上跨度为0.0到1.0、1.0到2.0等的系列。因此,每个系列的确切中心(即您希望标签显示的位置)将位于0.5、1.5等 我已经清理了你的代码,因为有很多无关的变量。请参阅中的评论
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)
我读到了保罗·伊万诺夫(Paul Ivanov)在其上发布的一个答案,该答案可能会以较少的复杂性解决这个问题。只需将索引设置如下。这将增加分组柱之间的间距
ind = np.arange(0,12,2)
实际上,我认为最好通过调整
figsize
和宽度来解决这个问题;这是我的输出,其中figsize=(2,7)
和width=0.3
:
顺便说一句,如果你使用pandas
wrappers(我还导入了seaborn
,这不是解决方案所必需的,但在我看来,这会使情节变得更加漂亮和现代):
另外,请注意,删除我的注释后,命令数量大大减少。虽然我认为Matplotlib的条形打印功能在某些方面可能会有一些小的改进,但这肯定不再像编写打印库那样简单。:)谢谢你的评论,我在编辑我的主要帖子时回复了你。从你上面写的,听起来你要么希望整个图形的宽度更小(这可以在创建图形的行中设置),要么希望边距本身更大,这将保持纵横比不变。您还可以调整宽度和扩展数据计算,以便在每个条之间留有余量。完成这一点只需要基本的代数。除了这三个想法,我不知道你在问什么。关于你对Matplotlib的抱怨,它是一个非常强大的绘图库,我在最近两次科学出版物中都使用了它。但是,如果你觉得它太复杂或“太像编写自己的绘图库”,没有人会阻止你尝试其他东西。我想你也可以在图形的最左边和最右边添加额外的边距。如果我们停下来想一想这到底意味着什么,最简单的方法就是将x极限从(0,2.)设置为类似(-1,3.)的值。你有在原始脚本中设置xlimit的功能,所以我想你能想出怎么做。回答得很好+1.寻求海生建议。谢谢
import pandas as pd
import seaborn
seaborn.set()
df = pd.DataFrame(groups, index=group_labels)
df.plot(kind='bar', legend=False, width=0.8, figsize=(2,5))
plt.show()