如何在刻度线之间对齐条形图中的条形(matplotlib)?

4

我需要在matplotlib中将图表中的条形图居中对齐到x轴刻度线之间。我尝试了使用选项align='edge',它会将柱形图移向刻度线的边缘,但不会使其在刻度之间对齐,我也不想扩大条形图宽度以消除条形之间的空白。

我的数据格式如下:

import matplotlib.pyplot as plt    
import numpy as np    
data = np.asarray([['7 Jan.',  60000],
                   ['14 Jan.', 37000],
                   ['21 Jan.', 32000]])

我想使用它来创建一个条形图:

x = data[:, 0]
y = data[:, 1].astype(np.int)
plt.bar(x, y, width=0.7, color='#A90000')
plt.show()

这将产生:

enter image description here

此外,有一个教程似乎是解决这个问题的方法,但我无法运行我的代码。任何帮助都将不胜感激。

1个回答

10
您正在绘制分类数据,即一些字符串,例如["Apple", "Banana", "Cherry"]。现在,如果您想在类别之间有条形图,那么不清楚这将是什么单位。 "Apple""Banana"之间的中间点是什么?也许是"Aubergine"?但人们无法知道。

因此,最好放弃分类图。现在,您当然可以将类别映射到数字。因此,第一个类别对应于0,第二个类别对应于1等等。然后很容易在中间位置放置条形图,在0.5、1.5...处。

import matplotlib.pyplot as plt    
import numpy as np    
data = np.asarray([['7 Jan.',  60000],
                   ['14 Jan.', 37000],
                   ['21 Jan.', 32000]])

cats = data[:, 0]
x = np.arange(len(cats)) + 0.5
y = data[:, 1].astype(np.int)

plt.bar(x, y, width=0.7, color='#A90000')
plt.xticks(x-0.5, cats)
plt.show()

enter image description here

一些情况下,图表似乎缺少最后一个标签,这在你的列表中并不存在。如果需要,你当然可以手动添加它。
另一种选择是使用实际日期。由于你的类别实际上对应于日期,因此这应该是可能的。
from datetime import datetime
import matplotlib.pyplot as plt    
import numpy as np    
data = np.asarray([['7 Jan.',  60000],
                   ['14 Jan.', 37000],
                   ['21 Jan.', 32000]])

# convert categories to dates
xt = [datetime.strptime(d, "%d %b.") for d in data[:, 0]]
# assume all dates are equally spaced
dt = (xt[1] - xt[0])/2
# get bar positions by adding half the interval to each date
x = [tp + dt for tp in xt]

y = data[:, 1].astype(np.int)

plt.bar(x, y, width=(0.7*2*dt).days, color='#A90000')
plt.xticks(xt, data[:, 0])
plt.show()

生成的图形与上面的视觉效果完全相同,但是x轴现在以日期时间为单位。这样可以使用刻度线和格式化程序,而不是手动放置刻度线和标签。
import numpy as np
from datetime import datetime
import matplotlib.pyplot as plt  
import matplotlib.dates as mdates


data = np.asarray([['7 Jan.',  60000],
                   ['14 Jan.', 37000],
                   ['21 Jan.', 32000]])

# convert categories to dates
xt = [datetime.strptime(d, "%d %b.") for d in data[:, 0]]
# assume all dates are equally spaced
dt = (xt[1] - xt[0])/2
# get bar positions by adding half the interval to each date
x = [tp + dt for tp in xt]

y = data[:, 1].astype(np.int)

plt.bar(x, y, width=(0.7*2*dt).days, color='#A90000')
plt.gca().xaxis.set_major_locator(mdates.WeekdayLocator(mdates.SU, interval=1))
plt.gca().xaxis.set_major_formatter(mdates.DateFormatter("%d %b %Y"))
plt.show()

enter image description here

现在标签对应实际日期,可以按所需格式进行格式化。您会注意到这里的日期是从1900年开始的,因此我们需要在每个星期日显示标签(因为1900年1月7日是星期日)。您可能希望将真实年份添加到您的数据中,以使此图正确。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接