6
votes

I'm not managing to plot matplotlib.finance.candlestick without the weekends (blank spaces between every 5 candlesticks). The example from Matplotlib's website doesn't exclude weekends either and the way to exclude weekends on other plots doesn't seem to apply to CandleSticks.

Has anybody come across this before?

ps. as requested, here is the example:

#!/usr/bin/env python
from pylab import *
from matplotlib.dates import  DateFormatter, WeekdayLocator, HourLocator, \
 DayLocator, MONDAY
from matplotlib.finance import quotes_historical_yahoo, candlestick,\
 plot_day_summary, candlestick2

# (Year, month, day) tuples suffice as args for quotes_historical_yahoo
date1 = ( 2004, 2, 1)
date2 = ( 2004, 4, 12 )


mondays = WeekdayLocator(MONDAY)        # major ticks on the mondays
alldays    = DayLocator()              # minor ticks on the days
weekFormatter = DateFormatter('%b %d')  # Eg, Jan 12
dayFormatter = DateFormatter('%d')      # Eg, 12

quotes = quotes_historical_yahoo('INTC', date1, date2)

fig = figure()
fig.subplots_adjust(bottom=0.2)
ax = fig.add_subplot(111)
ax.xaxis.set_major_locator(mondays)
ax.xaxis.set_minor_locator(alldays)
ax.xaxis.set_major_formatter(weekFormatter)

#plot_day_summary(ax, quotes, ticksize=3)
candlestick(ax, quotes, width=0.6)

ax.xaxis_date()
ax.autoscale_view()
setp( gca().get_xticklabels(), rotation=45, horizontalalignment='right')

show()
2
Could you please post an minimal example? - ev-br

2 Answers

4
votes

After your 'quotes' line:

weekday_quotes = [tuple([i]+list(quote[1:])) for i,quote in enumerate(quotes)]

then

candlestick(ax, weekday_quotes, width=0.6)

This will plot the data without the gaps between weekdays, now you have to change the xticks back to dates, preferably mondays. Assuming your first quote was a monday:

import matplotlib.dates as mdates

ax.set_xticks(range(0,len(weekday_quotes),5))
ax.set_xticklabels([mdates.num2date(quotes[index][0]).strftime('%b-%d') for index in ax.get_xticks()])

This is pretty gross but seems to get the job done - good luck!

0
votes

While @JMJR's answer works, I find this to be more robust:

def plot(x):
    plt.figure()
    plt.title("VIX curve")
    def idx(val=[0]):
        val[0] = val[0] + 1
        return val[0]
    d = collections.defaultdict(idx)
    # give each date an index
    [d[t] for t in sorted(x.index.get_level_values('baropen_datetime').unique())]
    # use the index
    x['idx'] = [d[t] for t in x.index.get_level_values('baropen_datetime')]
    # plot using index
    x.groupby('code').apply(lambda y: plt.plot(y.idx.values,
                                               y.close.values,
                                               label=y.index.get_level_values('code')[0]))
    plt.legend()
    plt.show()
    plt.close()