pythonmatplotlibscrollfinancecandlestick-chart

how to make srollable candelstick plot in Python?


I have following candlestick plot. I want to make it scrollable so that I can see more details. The current plot is too long to see details. I have found examples for making a line plot scrollable at here: Matplotlib: scrolling plot

However, updating a candlestick seems way more complicated than updating a line chart. The candlestick plot returns lines and patches. Can you help?

from pandas.io.data import get_data_yahoo
import matplotlib.pyplot as plt
from matplotlib import dates as mdates
from matplotlib import ticker as mticker
from matplotlib.finance import candlestick_ohlc
import datetime as dt
symbol = "GOOG"

data = get_data_yahoo(symbol, start = '2011-9-01', end = '2015-10-23')
data.reset_index(inplace=True)
data['Date']=mdates.date2num(data['Date'].astype(dt.date))
fig = plt.figure()
ax1 = plt.subplot2grid((1,1),(0,0))
plt.title('How to make it scrollable')
plt.ylabel('Price')
ax1.xaxis.set_major_locator(mticker.MaxNLocator(6))
ax1.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d'))

candlestick_ohlc(ax1,data.values,width=0.2)

Solution

  • You can plot the whole plot, and then use the slider widget to modify the axes area.

    I couldn't reproduce your data because I don't have the pandas.io.data library, so I modified the candlestick example from here, and added the slider.

    import matplotlib.pyplot as plt
    import datetime
    from matplotlib.widgets import Slider
    from matplotlib.finance import quotes_historical_yahoo_ohlc, candlestick_ohlc
    from matplotlib.dates import DateFormatter, WeekdayLocator,\
        DayLocator, MONDAY
    
    # (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')  # e.g., Jan 12
    dayFormatter = DateFormatter('%d')      # e.g., 12
    
    quotes = quotes_historical_yahoo_ohlc('INTC', date1, date2)
    if len(quotes) == 0:
        raise SystemExit
    
    fig, ax = plt.subplots()
    fig.subplots_adjust(bottom=0.2)
    ax.xaxis.set_major_locator(mondays)
    ax.xaxis.set_minor_locator(alldays)
    ax.xaxis.set_major_formatter(weekFormatter)
    #ax.xaxis.set_minor_formatter(dayFormatter)
    
    #plot_day_summary(ax, quotes, ticksize=3)
    candlestick_ohlc(ax, quotes, width=0.6)
    
    ax.xaxis_date()
    ax.autoscale_view()
    plt.axis([datetime.date(*date1).toordinal(), datetime.date(*date1).toordinal()+10, 18.5, 22.5])
    plt.setp(plt.gca().get_xticklabels(), rotation=45, horizontalalignment='right')
    
    
    axcolor = 'lightgoldenrodyellow'
    axpos = plt.axes([0.2, 0.05, 0.65, 0.03], axisbg=axcolor)
    
    
    spos = Slider(axpos, 'Position', datetime.date(*date1).toordinal(), datetime.date(*date2).toordinal())
    
    def update(val):
        pos = spos.val
        ax.axis([pos,pos+10, 18.5, 22.5])
        fig.canvas.draw_idle()
    
    spos.on_changed(update)
    
    plt.show()
    

    I hardcoded some values of the axes sizes and positions, please be careful when adapting to your code.

    Also same idea can be implemented to add a vertical scroll if needed.