matplotlib 如何跳过空日期(周末)在一个金融阴谋

jbose2ul  于 2023-10-24  发布在  其他
关注(0)|答案(8)|浏览(128)
ax.plot_date((dates, dates), (highs, lows), '-')

我目前正在使用这个命令用Matplotlib来绘制金融高点和低点。它工作得很好,但是我如何删除x轴上没有市场数据的日子留下的空白,比如周末和假期?
我有日期、高点、低点、收盘价和开盘价的列表,但我找不到任何用x轴来显示日期但不强制执行恒定刻度的图表的例子。

bqujaahr

bqujaahr1#

scikits.timeseries的一个广告功能是“创建具有智能间隔轴标签的时间序列图”。
您可以看到一些示例图here。在第一个示例(如下所示)中,“业务”频率用于数据,它自动排除了假期和周末等。它还屏蔽了缺失的数据点,您可以将其视为此图中的间隙,而不是线性插值。

u0njafvf

u0njafvf2#

最新的答案(2018)与Matplotlib 2.1.2,Python 2.7.12
函数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)

q9yhzks0

q9yhzks03#

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

ijnw1ujt

ijnw1ujt4#

对于无效或不存在的值,我通常使用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()
mwg9r5ms

mwg9r5ms5#

我再次遇到了这个问题,并且能够创建一个体面的函数来处理这个问题,特别是关于日内日期时间。

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

qyuhtwio6#

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

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

g6ll5ycj7#

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

inkz8wg98#

只需使用mplfinance https://github.com/matplotlib/mplfinance

import mplfinance as mpf
# df = 'ohlc dataframe'
mpf.plot(df)

相关问题