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

时间:2019-02-16 20:59:58

标签: python matplotlib

我需要将绘图中的条对齐以位于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

此外,还有this tutorial似乎可以解决此问题,但是我无法编写代码。任何帮助表示赞赏。

1 个答案:

答案 0 :(得分:1)

您正在绘制分类数据。那是一些像["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日是星期日)。您可能需要将实际年份添加到数据中,以使此图变得正确。