【问题标题】:How to align the bars in a bar chart between ticks (matplotlib)?如何在刻度之间对齐条形图中的条形(matplotlib)?
【发布时间】:2019-02-16 20:59:57
【问题描述】:

我需要将绘图中的条形对齐,使其在 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()

产量:

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

【问题讨论】:

    标签: python matplotlib


    【解决方案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()
    

    虽然情节看起来好像缺少最后一个标签,但它根本不存在于您的列表中。如果您愿意,当然可以手动添加。

    另一种方法是使用实​​际日期。因为您的类别实际上对应于应该可能的日期。

    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()
    

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

    【讨论】: