【问题标题】:How to skip empty dates (weekends) in a financial Matplotlib Python graph?如何在金融 Matplotlib Python 图中跳过空日期(周末)?
【发布时间】:2010-11-19 09:31:55
【问题描述】:
ax.plot_date((dates, dates), (highs, lows), '-')

我目前正在使用此命令通过Matplotlib 绘制财务高点和低点。效果很好,但是如何去除x轴上没有市场数据的日子留下的空白,例如周末和节假日?

我有日期、最高价、最低价、收盘价和开盘价的列表。我找不到任何使用 x 轴创建图表的示例,该图表显示日期但不强制执行恒定比例。

【问题讨论】:

    标签: python graph matplotlib financial


    【解决方案1】:

    scikits.timeseries 的广告功能之一是“创建具有智能间隔轴标签的时间序列图”。

    您可以看到一些示例图here。在第一个示例(如下所示)中,“业务”频率用于数据,自动排除节假日和周末等。它还掩盖了缺失的数据点,您在此图中将其视为间隙,而不是对其进行线性插值。

    【讨论】:

      【解决方案2】:

      我认为您需要通过使用 xticks 将刻度标签设置为代表日期的字符串来“人工合成”您想要的确切形式的绘图(当然,即使您的日期是等间距的,也将刻度放置在re 表示不等间距),然后使用普通的plot

      【讨论】:

        【解决方案3】:

        对于无效或不存在的值,我通常会使用 NumPy 的 NaN(不是数字)。它们由 Matplotlib 表示为图中的间隙,而 NumPy 是 pylab/Matplotlib 的一部分。

        >>> import pylab
        >>> xs = pylab.arange(10.) + 733632. # valid date range
        >>> ys = [1,2,3,2,pylab.nan,2,3,2,5,2.4] # some data (one undefined)
        >>> pylab.plot_date(xs, ys, ydate=False, linestyle='-', marker='')
        [<matplotlib.lines.Line2D instance at 0x0378D418>]
        >>> pylab.show()
        

        【讨论】:

          【解决方案4】:

          使用 Matplotlib 2.1.2、Python 2.7.12 的最新答案(2018 年)

          函数equidate_ax 可以处理数据点等距的简单日期x 轴所需的一切。在this example的基础上用ticker.FuncFormatter实现。

          from __future__ import division
          from matplotlib import pyplot as plt
          from matplotlib.ticker import FuncFormatter
          import numpy as np
          import datetime
          
          
          def equidate_ax(fig, ax, dates, fmt="%Y-%m-%d", label="Date"):
              """
              Sets all relevant parameters for an equidistant date-x-axis.
              Tick Locators are not affected (set automatically)
          
              Args:
                  fig: pyplot.figure instance
                  ax: pyplot.axis instance (target axis)
                  dates: iterable of datetime.date or datetime.datetime instances
                  fmt: Display format of dates
                  label: x-axis label
              Returns:
                  None
          
              """    
              N = len(dates)
              def format_date(index, pos):
                  index = np.clip(int(index + 0.5), 0, N - 1)
                  return dates[index].strftime(fmt)
              ax.xaxis.set_major_formatter(FuncFormatter(format_date))
              ax.set_xlabel(label)
              fig.autofmt_xdate()
          
          
          #
          # Some test data (with python dates)
          #
          dates = [datetime.datetime(year, month, day) for year, month, day in [
              (2018,2,1), (2018,2,2), (2018,2,5), (2018,2,6), (2018,2,7), (2018,2,28)
          ]]
          y = np.arange(6)
          
          
          # Create plots. Left plot is default with a gap
          fig, [ax1, ax2] = plt.subplots(1, 2)
          ax1.plot(dates, y, 'o-')
          ax1.set_title("Default")
          ax1.set_xlabel("Date")
          
          
          # Right plot will show equidistant series
          # x-axis must be the indices of your dates-list
          x = np.arange(len(dates))
          ax2.plot(x, y, 'o-')
          ax2.set_title("Equidistant Placement")
          equidate_ax(fig, ax2, dates)
          

          【讨论】:

            【解决方案5】:

            我再次遇到了这个问题,并且能够创建一个不错的函数来处理这个问题,尤其是关于日内日期时间。感谢@Primer for this answer.

            def plot_ts(ts, step=5, figsize=(10,7), title=''):
                """
                plot timeseries ignoring date gaps
            
                Params
                ------
                ts : pd.DataFrame or pd.Series
                step : int, display interval for ticks
                figsize : tuple, figure size
                title: str
                """
            
                fig, ax = plt.subplots(figsize=figsize)
                ax.plot(range(ts.dropna().shape[0]), ts.dropna())
                ax.set_title(title)
                ax.set_xticks(np.arange(len(ts.dropna())))
                ax.set_xticklabels(ts.dropna().index.tolist());
            
                # tick visibility, can be slow for 200,000+ ticks 
                xticklabels = ax.get_xticklabels() # generate list once to speed up function
                for i, label in enumerate(xticklabels):
                    if not i%step==0:
                        label.set_visible(False)  
                fig.autofmt_xdate()   
            

            【讨论】:

              【解决方案6】:

              您可以简单地将日期更改为字符串:

              import matplotlib.pyplot as plt
              import datetime
              
              f = plt.figure(1, figsize=(10,5))
              ax = f.add_subplot(111)
              
              today = datetime.datetime.today().date()
              yesterday = today - datetime.timedelta(days=1)
              three_days_later = today + datetime.timedelta(days=3)
              
              x_values = [yesterday, today, three_days_later]
              y_values = [75, 80, 90]
              
              x_values = [f'{x:%Y-%m-%d}' for x in x_values]
              ax.bar(x_values, y_values, color='green')
              plt.show()
              

              【讨论】:

                【解决方案7】:

                scikits.timeseries 功能已大部分移至 pandas,因此您现在可以重新采样数据框以仅包含工作日的值。

                >>>import pandas as pd
                >>>import matplotlib.pyplot as plt
                
                >>>s = pd.Series(list(range(10)), pd.date_range('2015-09-01','2015-09-10'))
                >>>s
                
                2015-09-01    0
                2015-09-02    1
                2015-09-03    2
                2015-09-04    3
                2015-09-05    4
                2015-09-06    5
                2015-09-07    6
                2015-09-08    7
                2015-09-09    8
                2015-09-10    9
                
                >>> s.resample('B', label='right', closed='right').last()
                2015-09-01    0
                2015-09-02    1
                2015-09-03    2
                2015-09-04    3
                2015-09-07    6
                2015-09-08    7
                2015-09-09    8
                2015-09-10    9
                

                然后正常绘制数据框

                s.resample('B', label='right', closed='right').last().plot()
                plt.show()
                

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 2019-11-28
                  • 2018-04-19
                  • 2019-09-07
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多