如何跳过财务图中的空日期(周末)

问题描述 投票:0回答:8
ax.plot_date((dates, dates), (highs, lows), '-')

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

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

python matplotlib graph time-series finance
8个回答

7
投票
Matplotlib 2.1.2、Python 2.7.12 的最新答案(2018)

函数

equidate_ax

 可以处理具有等距数据点间距的简单日期 x 轴所需的一切。基于
这个例子
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)


6
投票
我认为你需要通过使用

xticks

 将刻度标签设置为代表日期的字符串来“人工合成”你想要的确切形式的绘图(当然,即使你代表的日期,也要以等距间隔放置刻度不等距),然后使用普通的 
plot


6
投票
我通常会使用

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

5
投票
我再次遇到这个问题,并能够创建一个像样的函数来处理这个问题,特别是关于日内日期时间。感谢@Primer

给出了这个答案。

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

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

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

2
投票

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

0
投票
只需使用mplfinance

https://github.com/matplotlib/mplfinance

import mplfinance as mpf # df = 'ohlc dataframe' mpf.plot(df)
    
© www.soinside.com 2019 - 2024. All rights reserved.