【问题标题】:x-Axis ticks as datesx 轴刻度作为日期
【发布时间】:2021-03-05 05:12:23
【问题描述】:

我有一些数据要绘制,由两列组成,一列是金额count,另一列是实际记录的日期。绘制此图时,由于我有超过 2000 个日期,因此不要将每个日期都显示为 x 轴上的勾号更有意义,否则它将不可读。但是,我很难通过某种逻辑使日期显示在x-axis 上。我曾尝试使用 matplotlib 的内置刻度定位器,但它无法以某种方式工作。以下是数据预览:

PatientTraffic = pd.DataFrame({'count' : CleanData.groupby("TimeStamp").size()}).reset_index()
display(PatientTraffic.head(3000))

TimeStamp   count
0   2016-03-13 12:20:00 1
1   2016-03-13 13:39:00 1
2   2016-03-13 13:43:00 1
3   2016-03-13 16:00:00 1
4   2016-03-14 13:27:00 1
... ... ...
2088    2020-02-18 16:00:00 8
2089    2020-02-19 16:00:00 8
2090    2020-02-20 16:00:00 8
2091    2020-02-21 16:00:00 8
2092    2020-02-22 16:00:00 8
2093 rows × 2 columns

当我用这些设置来绘制它时:

PatientTrafficPerTimeStamp = PatientTraffic.plot.bar(
        x='TimeStamp', 
        y='count',
        figsize=(20,3),
        title = "Patient Traffic over Time"
        
    )
PatientTrafficPerTimeStamp.xaxis.set_major_locator(plt.MaxNLocator(3))

我希望得到一个条形图,其中x-axis 有三个刻度,一个在开头中间和结尾......也许我用错了。此外,似乎出现的刻度只是列中的前 3 个,这不是我想要的。任何帮助将不胜感激!

【问题讨论】:

    标签: python matplotlib


    【解决方案1】:

    如果您不需要那么多 xticks,您是否考虑过按日期分组? 回答您的问题,您可以使用:

    plt.xticks(ticks=[ 任何列表 ], labels=[ 标签列表 ])
    link to documentation

    【讨论】:

      【解决方案2】:

      你可能认为你有一个问题,但实际上你有两个 - 两者都是基于你使用便利函数这一事实。您最可能不知道的问题是 pandas 将条形图绘制为分类数据。这在大多数情况下是有意义的,但显然不是,如果您将时间戳数据作为 x 轴。看看是不是我编的:

      import matplotlib.pyplot as plt
      import pandas as pd
      
      fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10, 5))
      df = pd.read_csv("test.txt", sep = "\s{2,}", engine="python")
      #convert TS from string into datetime objects
      df.TS = pd.to_datetime(df.TS, format="%Y-%m-%d %H:%M:%S")
      
      #and plot it as you do directly from pandas that provides the data to matplotlib
      df.plot.bar(
              x="TS", 
              y="Val",
              ax=ax1,
              title="pandas version"    
          )
      
      #now plot the same data using matplotlib
      ax2.bar(df.TS, df.Val, width=22)
      ax2.tick_params(axis="x", labelrotation=90)
      ax2.set_title("matplotlib version")    
      
      plt.tight_layout()
      plt.show()
      

      样本输出:

      因此,我们应该直接从 matplotlib 中绘制它们,以防止丢失时间戳信息。显然,我们失去了 pandas 提供的一些便利,例如,我们必须调整条的宽度并标记轴。现在,您可以使用MaxNLocator 的另一个便利功能,但您注意到它已被编写为在大多数情况下都能正常工作,但您放弃了对刻度的精确定位的控制。为什么不使用FixedLocator 编写我们自己的定位器?

      import numpy as np
      import matplotlib.pyplot as plt
      import matplotlib.dates as mdates
      from matplotlib.ticker import FixedLocator
      import pandas as pd
      
      def myownMaxNLocator(datacol, n):
          datemin = mdates.date2num(datacol.min())
          datemax = mdates.date2num(datacol.max())
          xticks = np.linspace(datemin, datemax, n)
          return xticks
      
      
      fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10, 5))
      df = pd.read_csv("test.txt", sep = "\s{2,}", engine="python")
      df.TS = pd.to_datetime(df.TS, format="%Y-%m-%d %H:%M:%S")
          
      df.plot.bar(
              x="TS", 
              y="Val",
              ax=ax1,
              title="pandas version"    
          )
      
      ax2.bar(df.TS, df.Val, width=22)
      ax2.set_title("matplotlib version")
      dateticks = myownMaxNLocator(df.TS, 5)
      ax2.xaxis.set_major_locator(FixedLocator(dateticks))
      ax2.tick_params(axis="x", labelrotation=90)
      
      plt.tight_layout()
      plt.show()
      

      示例输出:

      在这里,刻度以最低值开始,以最高值结束。或者,您可以使用 LinearLocator 将刻度均匀分布在整个视图中:

      from matplotlib.ticker import LinearLocator
      ...
      ax2.bar(df.TS, df.Val, width=22)
      ax2.set_title("matplotlib version")
      ax2.xaxis.set_major_locator(LinearLocator(numticks=5))
      ax2.tick_params(axis="x", labelrotation=90)
      ...
      

      示例输出:

      样本数据存储在具有以下结构的文件中:

              TS                   Val
      0       2016-03-13 12:20:00  1
      1       2016-04-13 13:39:00  3
      2       2016-04-03 13:43:00  5
      3       2016-06-17 16:00:00  1
      4       2016-09-14 13:27:00  2
      2088    2017-02-08 16:00:00  7
      2089    2017-02-25 16:00:00  2
      2090    2018-02-20 16:00:00  8
      2091    2019-02-21 16:00:00  9
      2092    2020-02-22 16:00:00  8
      

      【讨论】:

      • 嗨!是的,这非常有帮助,谢谢。我现在最终使用了纯 Matplotlib 的绘图仪,因为它让事情变得更容易了一些。真的很感激,谢谢!
      猜你喜欢
      • 2020-10-01
      • 1970-01-01
      • 2015-07-13
      • 2013-01-04
      • 1970-01-01
      • 2016-06-25
      • 1970-01-01
      • 1970-01-01
      • 2018-11-13
      相关资源
      最近更新 更多