【问题标题】:Pandas Plot Bar Fixed Range Missing ValuesPandas Plot Bar 固定范围缺失值
【发布时间】:2021-07-17 11:02:27
【问题描述】:

我正在用 pandas.DataFrame 中的数据绘制条形图。我的代码如下

import pandas as pd
import matplotlib.pyplot as plot

from datetime import datetime


start_year = 2000
date_range = [ i + start_year for i in range(datetime.today().year - start_year)]

data = pd.DataFrame([
    [2015, 100], [2016, 110], [2017, 105], [2018, 109], [2019, 110], [2020, 116], [2021, 113]
], columns=["year", "value"])

chart = data.plot.bar(
    x="year",
    y="value",
    # xticks=date_range # , 
    xlim=[date_range[0], date_range[-1]]
)
plot.show()

结果图是:

我必须绘制其中的几个,其中的数据可能从 2000 年开始并在 2010 年结束,然后是另一个数据框,其中包含从 2010 年开始并在本年度结束的数据。

为了使这些图在视觉上具有可比性,我希望所有人都从同一年开始,在本例中为 2000 年,并在当前年结束。如果给定年份没有值,则可以使用 0。在本例中,例如,我使用了 2000 年,但也可以从 2005、2006 或 2010 年开始。

我怎样才能实现我正在寻找的东西?我尝试设置 xticks 和 xlim,但使用 xticks,数据会全部偏向一侧,就好像两者之间有数千个值一样。这很奇怪,因为我使用的是 int 值。

谢谢

【问题讨论】:

    标签: python-3.x pandas matplotlib bar-chart


    【解决方案1】:

    您可以准备好您的数据框,以便它拥有您想要的所有年份。 正确 merge() 到具有所有所需年份的数据框

    data = pd.DataFrame([
        [2015, 100], [2016, 110], [2017, 105], [2018, 109], [2019, 110], [2020, 116], [2021, 113]
    ], columns=["year", "value"])
    
    # NB range is zero indexed, hence endyear + 1
    data.merge(pd.DataFrame({"year":range(2010,2021+1)}), on="year", how="right").plot(kind="bar", x="year", y="value")
    

    【讨论】:

    • 谢谢,我已经用过了,忘记了。不过,我希望有一个更“原生”的解决方案。如果没有其他答案有更好的解决方案,我会等几天,然后将此答案标记为已接受
    【解决方案2】:

    如果您使用pyplot.bar(),您可以将set_xlim() 设置为您想要的范围(边界上有一些额外的填充):

    fig, ax = plt.subplots(figsize=(10,6))
    ax.bar(data.year, data.value, align='center')
    
    # expand xlim to date_range
    date_range = range(2000, 2021+1)
    ax.set_xlim(date_range[0]-1, date_range[-1]+1) # pad both ends
    
    # set xtick on every bar
    ax.set_xticks(date_range)
    ax.set_xticklabels(date_range)
    plt.xticks(rotation=90)
    

    请注意,matplotlib 的 bar() 仅在 x=2000 处绘制 2000 年,而 pandas 的 plot.bar() 自动将 x 轴移动到 0 并更改字符串标签以匹配数据(第一个栏位于 @987654330 @ 带有标签“2000”,第二条位于x=1.5,带有标签“2001”,...)。你仍然可以对 pandas 做同样的事情,但是转移/重新标记所有内容会更加麻烦。

    【讨论】:

    • 这是一种有趣的方法,谢谢,但重新索引不是一项昂贵的操作吗?我必须绘制其中的几个,因此重新索引数据帧会变得很耗时(因此我一直在寻找一种更原生的方法)
    • @lsabi 不确定,我认为reindex() 是这里的“原生”方法。我经常使用它没有问题,但如果不知道你的真实数据就很难说。
    • 我的真实数据是产品的年度数据。考虑到我有数千个,效率是一个问题。对于“原生”,我的意思是通过某种方式告诉 matplotlib,比如 xticks,传递一个 x 值(年份)数组并使用数据来填充可以填充的内容
    • 真的有原生方式吗?我希望它比reindex() 更有效率
    • @lsabi pandas 将 x 刻度移动到 0 并更改字符串标签以匹配数据(因此 x=0.5 被标记为 '1999',x=1.5 是 '2000',...)。 matplotlib 只是在x=1999 处绘制了 1999 年,因此只需 set_xlim()
    猜你喜欢
    • 1970-01-01
    • 2015-08-18
    • 2016-02-09
    • 1970-01-01
    • 1970-01-01
    • 2021-07-21
    • 2014-02-21
    相关资源
    最近更新 更多