How to skip empty dates (weekends) in a financial

2020-01-30 09:06发布

ax.plot_date((dates, dates), (highs, lows), '-')

I'm currently using this command to plot financial highs and lows using Matplotlib. It works great, but how do I remove the blank spaces in the x-axis left by days without market data, such as weekends and holidays?

I have lists of dates, highs, lows, closes and opens. I can't find any examples of creating a graph with an x-axis that show dates but doesn't enforce a constant scale.

7条回答
闹够了就滚
2楼-- · 2020-01-30 09:23

I ran into this problem again and was able to create a decent function to handle this issue, especially concerning intraday datetimes. Credit to @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()   
查看更多
家丑人穷心不美
3楼-- · 2020-01-30 09:27

Up to date answer (2018) with Matplotlib 2.1.2, Python 2.7.12

The function equidate_ax handles everything you need for a simple date x-axis with equidistant spacing of data points. Realised with ticker.FuncFormatter based on this example.

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)

Comparison of default plotting method and equidistant x-axis

查看更多
再贱就再见
4楼-- · 2020-01-30 09:28

I will typically use NumPy's NaN (not a number) for values that are invalid or not present. They are represented by Matplotlib as gaps in the plot and NumPy is part of 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楼-- · 2020-01-30 09:34

One of the advertised features of scikits.timeseries is "Create time series plots with intelligently spaced axis labels".

You can see some example plots here. In the first example (shown below) the 'business' frequency is used for the data, which automatically excludes holidays and weekends and the like. It also masks missing data points, which you see as gaps in this plot, rather than linearly interpolating them.

alt text

查看更多
贼婆χ
6楼-- · 2020-01-30 09:37

There's an example of how to do this on the Matplotlib site:

https://matplotlib.org/gallery/ticks_and_spines/date_index_formatter.html

查看更多
Anthone
7楼-- · 2020-01-30 09:40

scikits.timeseries functionality has largely been moved to pandas, so you can now resample a dataframe to only include the values on weekdays.

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

and then to plot the dataframe as normal

s.resample('B', label='right', closed='right').last().plot()
plt.show()
查看更多
登录 后发表回答