简体   繁体   中英

How to Remove Weekends in Matplotlib Candlestick Chart?

When plotting a candlestick chart in matplotlib , the plot leaves unsightly gaps over weekends. This happens because of breaks in the data due to markets being closed on weekends. How can the gaps over weekends be removed?

Below is a simple example demonstrating the presence of gaps in the plot.

import matplotlib.pyplot as plt
from matplotlib.finance import quotes_historical_yahoo_ohlc, candlestick_ohlc

date1, date2 = [(2006, 6, 1), (2006, 8, 1)]
quotes_mpl = quotes_historical_yahoo_ohlc('INTC', date1, date2)

fig, ax = plt.subplots()
candlestick_ohlc(ax, quotes_mpl)
ax.xaxis_date()
plt.xticks(rotation=45)

Weekend gaps are shown by green arrows.

在此处输入图像描述

Unfortunately, neither matplotlib nor pandas to my knowledge has a built-in way of only plotting weekday data. But, as is shown in this matplotlib example , custom tick formatting can be done to artificially skip over weekends in a sort of hacky way.

The main idea is to reindex your data sequentially (so that there are no gaps), and then manually set the xticks according to the range of dates that you know it ought to be. The matplotlib candlestick chart is a bit special* so it cannot simply be thrown into the example linked to above. So instead, I wrote the below helper function to make skipping over missing data more manageable.

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
from matplotlib.finance import quotes_historical_yahoo_ohlc, candlestick_ohlc


def weekday_candlestick(ohlc_data, ax, fmt='%b %d', freq=7, **kwargs):
    """ Wrapper function for matplotlib.finance.candlestick_ohlc
        that artificially spaces data to avoid gaps from weekends """

    # Convert data to numpy array
    ohlc_data_arr = np.array(ohlc_data)
    ohlc_data_arr2 = np.hstack(
        [np.arange(ohlc_data_arr[:,0].size)[:,np.newaxis], ohlc_data_arr[:,1:]])
    ndays = ohlc_data_arr2[:,0]  # array([0, 1, 2, ... n-2, n-1, n])

    # Convert matplotlib date numbers to strings based on `fmt`
    dates = mdates.num2date(ohlc_data_arr[:,0])
    date_strings = []
    for date in dates:
        date_strings.append(date.strftime(fmt))

    # Plot candlestick chart
    candlestick_ohlc(ax, ohlc_data_arr2, **kwargs)

    # Format x axis
    ax.set_xticks(ndays[::freq])
    ax.set_xticklabels(date_strings[::freq], rotation=45, ha='right')
    ax.set_xlim(ndays.min(), ndays.max())

    plt.show()

Here's a couple use cases of the above function.

# Get data using quotes_historical_yahoo_ohlc
date1, date2 = [(2006, 6, 1), (2006, 8, 1)]
date3, date4 = [(2006, 5, 15), (2008, 4, 1)]
data_1 = quotes_historical_yahoo_ohlc('INTC', date1, date2)
data_2 = quotes_historical_yahoo_ohlc('INTC', date3, date4)

# Create figure with 2 axes
fig, axes = plt.subplots(ncols=2, figsize=(14, 6))

weekday_candlestick(data_1, ax=axes[0], fmt='%b %d', freq=3, width=0.5)
weekday_candlestick(data_2, ax=axes[1], fmt='%b %d %Y', freq=30)

# Set the plot titles
axes[0].set_title('Shorter Range Stock Prices')
axes[1].set_title('Longer Range Stock Prices')

When run, it produces the below plot (free of weekend gaps).

在此处输入图像描述

*It takes a list of tuples--the time, open, high, low, and close values, which is rather unique.

The new version of matplotlib finance that will do this for you automatically.

See https://pypi.org/project/mplfinance/

finplot automatically skips days left out in the index. It also has other advantages to mplfinance and plotly.

import finplot as fplt
import yfinance as yf

df = yf.download('INTC', '2020-06-01')
fplt.candlestick_ochl(df[['Open','Close','High','Low']])
fplt.show()

在此处输入图像描述

Disclaimer: I'm the author of said lib.

Add this to your plot

show_nontrading=False

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM