diff --git a/doc/api/api_changes.rst b/doc/api/api_changes.rst index a17ef4971e52..721e0549117c 100644 --- a/doc/api/api_changes.rst +++ b/doc/api/api_changes.rst @@ -48,8 +48,16 @@ original location: - mstream -> `from matplotlib import stream as mstream` - mtable -> `from matplotlib import table as mtable` + +* In :module:`~matplotlib.finance`, almost all functions have been deprecated and + replaced with a pair of functions name `*_ochl` and `*_ohlc`. The former is + 'open-close-high-low' order of quotes, and what the module used and the later + is 'open-high-low-close' order of quotes, which is the standard in finance. + + .. _changes_in_1_3: + Changes in 1.3.x ================ diff --git a/doc/api/finance_api.rst b/doc/api/finance_api.rst new file mode 100644 index 000000000000..9b2c5021c675 --- /dev/null +++ b/doc/api/finance_api.rst @@ -0,0 +1,12 @@ +******* +finance +******* + + +:mod:`matplotlib.finance` +========================= + +.. automodule:: matplotlib.finance + :members: + :undoc-members: + :show-inheritance: diff --git a/doc/api/index.rst b/doc/api/index.rst index 1713b439c411..061aff6ac1cd 100644 --- a/doc/api/index.rst +++ b/doc/api/index.rst @@ -28,6 +28,7 @@ colors_api.rst dates_api.rst figure_api.rst + finance_api.rst font_manager_api.rst gridspec_api.rst legend_api.rst diff --git a/examples/pylab_examples/date_demo1.py b/examples/pylab_examples/date_demo1.py index 51b852a4951e..fbd61356578b 100644 --- a/examples/pylab_examples/date_demo1.py +++ b/examples/pylab_examples/date_demo1.py @@ -15,17 +15,17 @@ """ import matplotlib.pyplot as plt -from matplotlib.finance import quotes_historical_yahoo +from matplotlib.finance import quotes_historical_yahoo_ochl from matplotlib.dates import YearLocator, MonthLocator, DateFormatter import datetime -date1 = datetime.date( 1995, 1, 1 ) -date2 = datetime.date( 2004, 4, 12 ) +date1 = datetime.date(1995, 1, 1) +date2 = datetime.date(2004, 4, 12) -years = YearLocator() # every year -months = MonthLocator() # every month +years = YearLocator() # every year +months = MonthLocator() # every month yearsFmt = DateFormatter('%Y') -quotes = quotes_historical_yahoo( +quotes = quotes_historical_yahoo_ochl( 'INTC', date1, date2) if len(quotes) == 0: raise SystemExit diff --git a/examples/pylab_examples/date_demo2.py b/examples/pylab_examples/date_demo2.py index d6420f97674c..8794447acdb1 100755 --- a/examples/pylab_examples/date_demo2.py +++ b/examples/pylab_examples/date_demo2.py @@ -9,22 +9,22 @@ import datetime import matplotlib.pyplot as plt from matplotlib.dates import MONDAY -from matplotlib.finance import quotes_historical_yahoo +from matplotlib.finance import quotes_historical_yahoo_ochl from matplotlib.dates import MonthLocator, WeekdayLocator, DateFormatter -date1 = datetime.date( 2002, 1, 5 ) -date2 = datetime.date( 2003, 12, 1 ) +date1 = datetime.date(2002, 1, 5) +date2 = datetime.date(2003, 12, 1) # every monday -mondays = WeekdayLocator(MONDAY) +mondays = WeekdayLocator(MONDAY) # every 3rd month -months = MonthLocator(range(1,13), bymonthday=1, interval=3) +months = MonthLocator(range(1, 13), bymonthday=1, interval=3) monthsFmt = DateFormatter("%b '%y") -quotes = quotes_historical_yahoo('INTC', date1, date2) +quotes = quotes_historical_yahoo_ochl('INTC', date1, date2) if len(quotes) == 0: print ('Found no quotes') raise SystemExit diff --git a/examples/pylab_examples/finance_demo.py b/examples/pylab_examples/finance_demo.py index 9d0318e2f234..409b8cdd9a80 100644 --- a/examples/pylab_examples/finance_demo.py +++ b/examples/pylab_examples/finance_demo.py @@ -1,21 +1,21 @@ #!/usr/bin/env python import matplotlib.pyplot as plt -from matplotlib.dates import DateFormatter, WeekdayLocator, HourLocator, \ +from matplotlib.dates import DateFormatter, WeekdayLocator,\ DayLocator, MONDAY -from matplotlib.finance import quotes_historical_yahoo, candlestick,\ - plot_day_summary, candlestick2 +from matplotlib.finance import quotes_historical_yahoo_ohlc, candlestick_ohlc + # (Year, month, day) tuples suffice as args for quotes_historical_yahoo -date1 = ( 2004, 2, 1) -date2 = ( 2004, 4, 12 ) +date1 = (2004, 2, 1) +date2 = (2004, 4, 12) mondays = WeekdayLocator(MONDAY) # major ticks on the mondays -alldays = DayLocator() # minor ticks on the days +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('INTC', date1, date2) +quotes = quotes_historical_yahoo_ohlc('INTC', date1, date2) if len(quotes) == 0: raise SystemExit @@ -27,11 +27,10 @@ #ax.xaxis.set_minor_formatter(dayFormatter) #plot_day_summary(ax, quotes, ticksize=3) -candlestick(ax, quotes, width=0.6) +candlestick_ohlc(ax, quotes, width=0.6) ax.xaxis_date() ax.autoscale_view() -plt.setp( plt.gca().get_xticklabels(), rotation=45, horizontalalignment='right') +plt.setp(plt.gca().get_xticklabels(), rotation=45, horizontalalignment='right') plt.show() - diff --git a/lib/matplotlib/finance.py b/lib/matplotlib/finance.py index c9a6358a6a35..106822d64caf 100644 --- a/lib/matplotlib/finance.py +++ b/lib/matplotlib/finance.py @@ -1,10 +1,16 @@ """ -A collection of modules for collecting, analyzing and plotting +A collection of functions for collecting, analyzing and plotting financial data. User contributions welcome! +This module is deprecated in 1.4 and will be moved to `mpl_toolkits` +or it's own project in the future. + """ from __future__ import division, print_function -import contextlib, os, sys, warnings +import contextlib +import os +import sys +import warnings from urllib2 import urlopen if sys.version_info[0] < 3: @@ -26,6 +32,7 @@ from matplotlib.patches import Rectangle from matplotlib.transforms import Affine2D +from matplotlib.cbook import mplDeprecation cachedir = get_cachedir() # cachedir will be None if there is no writable directory. @@ -37,7 +44,20 @@ cachedir = None -stock_dt = np.dtype([('date', object), +stock_dt_ohlc = np.dtype([('date', object), + ('year', np.int16), + ('month', np.int8), + ('day', np.int8), + ('d', np.float), # mpl datenum + ('open', np.float), + ('high', np.float), + ('low', np.float), + ('close', np.float), + ('volume', np.float), + ('aclose', np.float)]) + + +stock_dt_ochl = np.dtype([('date', object), ('year', np.int16), ('month', np.int8), ('day', np.int8), @@ -49,13 +69,68 @@ ('volume', np.float), ('aclose', np.float)]) +_warn_str = ("This function has been deprecated in 1.4 in favor " + "of `{fun}_ochl`, " + "which maintains the original argument order, " + "or `{fun}_ohlc`, " + "which uses the open-high-low-close order. " + "This function will be removed in 1.5") + + +def parse_yahoo_historical_ochl(fh, adjusted=True, asobject=False): + """Parse the historical data in file handle fh from yahoo finance. + + Parameters + ---------- + + adjusted : bool + If True (default) replace open, close, high, low prices with + their adjusted values. The adjustment is by a scale factor, S = + adjusted_close/close. Adjusted prices are actual prices + multiplied by S. + + Volume is not adjusted as it is already backward split adjusted + by Yahoo. If you want to compute dollars traded, multiply volume + by the adjusted close, regardless of whether you choose adjusted + = True|False. + + + asobject : bool or None + If False (default for compatibility with earlier versions) + return a list of tuples containing + + d, open, close, high, low, volume + + If None (preferred alternative to False), return + a 2-D ndarray corresponding to the list of tuples. + + Otherwise return a numpy recarray with + + date, year, month, day, d, open, close, high, low, + volume, adjusted_close + + where d is a floating poing representation of date, + as returned by date2num, and date is a python standard + library datetime.date instance. + + The name of this kwarg is a historical artifact. Formerly, + True returned a cbook Bunch + holding 1-D ndarrays. The behavior of a numpy recarray is + very similar to the Bunch. -def parse_yahoo_historical(fh, adjusted=True, asobject=False): """ - Parse the historical data in file handle fh from yahoo finance. + return _parse_yahoo_historical(fh, adjusted=adjusted, asobject=asobject, + ochl=True) + - *adjusted* - If True (default) replace open, close, high, and low prices with +def parse_yahoo_historical_ohlc(fh, adjusted=True, asobject=False): + """Parse the historical data in file handle fh from yahoo finance. + + Parameters + ---------- + + adjusted : bool + If True (default) replace open, high, low, close prices with their adjusted values. The adjustment is by a scale factor, S = adjusted_close/close. Adjusted prices are actual prices multiplied by S. @@ -66,7 +141,59 @@ def parse_yahoo_historical(fh, adjusted=True, asobject=False): = True|False. - *asobject* + asobject : bool or None + If False (default for compatibility with earlier versions) + return a list of tuples containing + + d, open, high, low, close, volume + + If None (preferred alternative to False), return + a 2-D ndarray corresponding to the list of tuples. + + Otherwise return a numpy recarray with + + date, year, month, day, d, open, high, low, close, + volume, adjusted_close + + where d is a floating poing representation of date, + as returned by date2num, and date is a python standard + library datetime.date instance. + + The name of this kwarg is a historical artifact. Formerly, + True returned a cbook Bunch + holding 1-D ndarrays. The behavior of a numpy recarray is + very similar to the Bunch. + """ + return _parse_yahoo_historical(fh, adjusted=adjusted, asobject=asobject, + ochl=False) + + +def parse_yahoo_historical(fh, adjusted=True, asobject=False): + """Parse the historical data in file handle fh from yahoo finance. + + + This function has been deprecated in 1.4 in favor of + `parse_yahoo_historical_ochl`, which maintains the original argument + order, or `parse_yahoo_historical_ohlc`, which uses the + open-high-low-close order. This function will be removed in 1.5 + + + Parameters + ---------- + + adjusted : bool + If True (default) replace open, close, high, low prices with + their adjusted values. The adjustment is by a scale factor, S = + adjusted_close/close. Adjusted prices are actual prices + multiplied by S. + + Volume is not adjusted as it is already backward split adjusted + by Yahoo. If you want to compute dollars traded, multiply volume + by the adjusted close, regardless of whether you choose adjusted + = True|False. + + + asobject : bool or None If False (default for compatibility with earlier versions) return a list of tuples containing @@ -78,7 +205,7 @@ def parse_yahoo_historical(fh, adjusted=True, asobject=False): Otherwise return a numpy recarray with date, year, month, day, d, open, close, high, low, - volume, aclose + volume, adjusted_close where d is a floating poing representation of date, as returned by date2num, and date is a python standard @@ -89,18 +216,86 @@ def parse_yahoo_historical(fh, adjusted=True, asobject=False): holding 1-D ndarrays. The behavior of a numpy recarray is very similar to the Bunch. + ochl : bool + Temporary argument to select between ochl and ohlc ordering. + Defaults to True to preserve original functionality. + """ - lines = fh.readlines() + warnings.warn(_warn_str.format(fun='parse_yahoo_historical'), + mplDeprecation) + + return _parse_yahoo_historical(fh, adjusted=adjusted, asobject=asobject, + ochl=True) + + +def _parse_yahoo_historical(fh, adjusted=True, asobject=False, + ochl=True): + """Parse the historical data in file handle fh from yahoo finance. + + + Parameters + ---------- + + adjusted : bool + If True (default) replace open, high, low, close prices with + their adjusted values. The adjustment is by a scale factor, S = + adjusted_close/close. Adjusted prices are actual prices + multiplied by S. + + Volume is not adjusted as it is already backward split adjusted + by Yahoo. If you want to compute dollars traded, multiply volume + by the adjusted close, regardless of whether you choose adjusted + = True|False. - results = [] - datefmt = '%Y-%m-%d' + asobject : bool or None + If False (default for compatibility with earlier versions) + return a list of tuples containing - for line in lines[1:]: + d, open, high, low, close, volume + + or + + d, open, close, high, low, volume + + depending on `ochl` + + If None (preferred alternative to False), return + a 2-D ndarray corresponding to the list of tuples. + + Otherwise return a numpy recarray with + + date, year, month, day, d, open, high, low, close, + volume, adjusted_close + + where d is a floating poing representation of date, + as returned by date2num, and date is a python standard + library datetime.date instance. + + The name of this kwarg is a historical artifact. Formerly, + True returned a cbook Bunch + holding 1-D ndarrays. The behavior of a numpy recarray is + very similar to the Bunch. + + ochl : bool + Selects between ochl and ohlc ordering. + Defaults to True to preserve original functionality. + + """ + if ochl: + stock_dt = stock_dt_ochl + else: + stock_dt = stock_dt_ohlc + + results = [] + + # datefmt = '%Y-%m-%d' + fh.readline() # discard heading + for line in fh: vals = line.split(',') - if len(vals)!=7: + if len(vals) != 7: continue # add warning? datestr = vals[0] #dt = datetime.date(*time.strptime(datestr, datefmt)[:3]) @@ -108,31 +303,41 @@ def parse_yahoo_historical(fh, adjusted=True, asobject=False): # format, we don't need it. dt = datetime.date(*[int(val) for val in datestr.split('-')]) dnum = date2num(dt) - open, high, low, close = [float(val) for val in vals[1:5]] + open, high, low, close = [float(val) for val in vals[1:5]] volume = float(vals[5]) aclose = float(vals[6]) + if ochl: + results.append((dt, dt.year, dt.month, dt.day, + dnum, open, close, high, low, volume, aclose)) - results.append((dt, dt.year, dt.month, dt.day, - dnum, open, close, high, low, volume, aclose)) + else: + results.append((dt, dt.year, dt.month, dt.day, + dnum, open, high, low, close, volume, aclose)) results.reverse() d = np.array(results, dtype=stock_dt) if adjusted: scale = d['aclose'] / d['close'] scale[np.isinf(scale)] = np.nan d['open'] *= scale - d['close'] *= scale d['high'] *= scale d['low'] *= scale + d['close'] *= scale if not asobject: # 2-D sequence; formerly list of tuples, now ndarray ret = np.zeros((len(d), 6), dtype=np.float) - ret[:,0] = d['d'] - ret[:,1] = d['open'] - ret[:,2] = d['close'] - ret[:,3] = d['high'] - ret[:,4] = d['low'] - ret[:,5] = d['volume'] + ret[:, 0] = d['d'] + if ochl: + ret[:, 1] = d['open'] + ret[:, 2] = d['close'] + ret[:, 3] = d['high'] + ret[:, 4] = d['low'] + else: + ret[:, 1] = d['open'] + ret[:, 2] = d['high'] + ret[:, 3] = d['low'] + ret[:, 4] = d['close'] + ret[:, 5] = d['volume'] if asobject is None: return ret return [tuple(row) for row in ret] @@ -140,49 +345,65 @@ def parse_yahoo_historical(fh, adjusted=True, asobject=False): return d.view(np.recarray) # Close enough to former Bunch return -def fetch_historical_yahoo(ticker, date1, date2, cachename=None,dividends=False): +def fetch_historical_yahoo(ticker, date1, date2, cachename=None, + dividends=False): """ Fetch historical data for ticker between date1 and date2. date1 and date2 are date or datetime instances, or (year, month, day) sequences. - Ex: - fh = fetch_historical_yahoo('^GSPC', (2000, 1, 1), (2001, 12, 31)) + Parameters + ---------- + ticker : str + ticker + + date1 : sequence of form (year, month, day), `datetime`, or `date` + start date + date2 : sequence of form (year, month, day), `datetime`, or `date` + end date + + cachename : str + cachename is the name of the local file cache. If None, will + default to the md5 hash or the url (which incorporates the ticker + and date range) + + dividends : bool + set dividends=True to return dividends instead of price data. With + this option set, parse functions will not work - cachename is the name of the local file cache. If None, will - default to the md5 hash or the url (which incorporates the ticker - and date range) + Returns + ------- + file_handle : file handle + a file handle is returned - set dividends=True to return dividends instead of price data. With - this option set, parse functions will not work - a file handle is returned + Examples + -------- + >>> fh = fetch_historical_yahoo('^GSPC', (2000, 1, 1), (2001, 12, 31)) + """ ticker = ticker.upper() - if iterable(date1): - d1 = (date1[1]-1, date1[2], date1[0]) + d1 = (date1[1] - 1, date1[2], date1[0]) else: - d1 = (date1.month-1, date1.day, date1.year) + d1 = (date1.month - 1, date1.day, date1.year) if iterable(date2): - d2 = (date2[1]-1, date2[2], date2[0]) + d2 = (date2[1] - 1, date2[2], date2[0]) else: - d2 = (date2.month-1, date2.day, date2.year) - + d2 = (date2.month - 1, date2.day, date2.year) if dividends: - g='v' + g = 'v' verbose.report('Retrieving dividends instead of prices') else: - g='d' - - urlFmt = 'http://ichart.yahoo.com/table.csv?a=%d&b=%d&c=%d&d=%d&e=%d&f=%d&s=%s&y=0&g=%s&ignore=.csv' + g = 'd' + urlFmt = ('http://ichart.yahoo.com/table.csv?a=%d&b=%d&' + + 'c=%d&d=%d&e=%d&f=%d&s=%s&y=0&g=%s&ignore=.csv') - url = urlFmt % (d1[0], d1[1], d1[2], - d2[0], d2[1], d2[2], ticker, g) - + url = urlFmt % (d1[0], d1[1], d1[2], + d2[0], d2[1], d2[2], ticker, g) # Cache the finance data if cachename is supplied, or there is a writable # cache directory. @@ -191,13 +412,15 @@ def fetch_historical_yahoo(ticker, date1, date2, cachename=None,dividends=False) if cachename is not None: if os.path.exists(cachename): fh = open(cachename) - verbose.report('Using cachefile %s for %s'%(cachename, ticker)) + verbose.report('Using cachefile %s for ' + '%s' % (cachename, ticker)) else: mkdirs(os.path.abspath(os.path.dirname(cachename))) with contextlib.closing(urlopen(url)) as urlfh: with open(cachename, 'wb') as fh: fh.write(urlfh.read()) - verbose.report('Saved %s data to cache file %s'%(ticker, cachename)) + verbose.report('Saved %s data to cache file ' + '%s' % (ticker, cachename)) fh = open(cachename, 'r') return fh @@ -206,27 +429,177 @@ def fetch_historical_yahoo(ticker, date1, date2, cachename=None,dividends=False) def quotes_historical_yahoo(ticker, date1, date2, asobject=False, - adjusted=True, cachename=None): + adjusted=True, cachename=None): + """ Get historical data for ticker between date1 and date2. + + + This function has been deprecated in 1.4 in favor of + `quotes_yahoo_historical_ochl`, which maintains the original argument + order, or `quotes_yahoo_historical_ohlc`, which uses the + open-high-low-close order. This function will be removed in 1.5 + + See :func:`parse_yahoo_historical` for explanation of output formats + and the *asobject* and *adjusted* kwargs. + + Parameters + ---------- + ticker : str + stock ticker + + date1 : sequence of form (year, month, day), `datetime`, or `date` + start date + + date2 : sequence of form (year, month, day), `datetime`, or `date` + end date + + cachename : str or `None` + is the name of the local file cache. If None, will + default to the md5 hash or the url (which incorporates the ticker + and date range) + + Examples + -------- + >>> sp = f.quotes_historical_yahoo('^GSPC', d1, d2, + asobject=True, adjusted=True) + >>> returns = (sp.open[1:] - sp.open[:-1])/sp.open[1:] + >>> [n,bins,patches] = hist(returns, 100) + >>> mu = mean(returns) + >>> sigma = std(returns) + >>> x = normpdf(bins, mu, sigma) + >>> plot(bins, x, color='red', lw=2) + + """ + warnings.warn(_warn_str.format(fun='quotes_historical_yahoo'), + mplDeprecation) + + return _quotes_historical_yahoo(ticker, date1, date2, asobject=asobject, + adjusted=adjusted, cachename=cachename, + ochl=True) + + +def quotes_historical_yahoo_ochl(ticker, date1, date2, asobject=False, + adjusted=True, cachename=None): + """ Get historical data for ticker between date1 and date2. + + + See :func:`parse_yahoo_historical` for explanation of output formats + and the *asobject* and *adjusted* kwargs. + + Parameters + ---------- + ticker : str + stock ticker + + date1 : sequence of form (year, month, day), `datetime`, or `date` + start date + + date2 : sequence of form (year, month, day), `datetime`, or `date` + end date + + cachename : str or `None` + is the name of the local file cache. If None, will + default to the md5 hash or the url (which incorporates the ticker + and date range) + + Examples + -------- + >>> sp = f.quotes_historical_yahoo_ochl('^GSPC', d1, d2, + asobject=True, adjusted=True) + >>> returns = (sp.open[1:] - sp.open[:-1])/sp.open[1:] + >>> [n,bins,patches] = hist(returns, 100) + >>> mu = mean(returns) + >>> sigma = std(returns) + >>> x = normpdf(bins, mu, sigma) + >>> plot(bins, x, color='red', lw=2) + + """ + + return _quotes_historical_yahoo(ticker, date1, date2, asobject=asobject, + adjusted=adjusted, cachename=cachename, + ochl=True) + + +def quotes_historical_yahoo_ohlc(ticker, date1, date2, asobject=False, + adjusted=True, cachename=None): + """ Get historical data for ticker between date1 and date2. + + + See :func:`parse_yahoo_historical` for explanation of output formats + and the *asobject* and *adjusted* kwargs. + + Parameters + ---------- + ticker : str + stock ticker + + date1 : sequence of form (year, month, day), `datetime`, or `date` + start date + + date2 : sequence of form (year, month, day), `datetime`, or `date` + end date + + cachename : str or `None` + is the name of the local file cache. If None, will + default to the md5 hash or the url (which incorporates the ticker + and date range) + + Examples + -------- + >>> sp = f.quotes_historical_yahoo_ohlc('^GSPC', d1, d2, + asobject=True, adjusted=True) + >>> returns = (sp.open[1:] - sp.open[:-1])/sp.open[1:] + >>> [n,bins,patches] = hist(returns, 100) + >>> mu = mean(returns) + >>> sigma = std(returns) + >>> x = normpdf(bins, mu, sigma) + >>> plot(bins, x, color='red', lw=2) + """ - Get historical data for ticker between date1 and date2. date1 and - date2 are datetime instances or (year, month, day) sequences. + + return _quotes_historical_yahoo(ticker, date1, date2, asobject=asobject, + adjusted=adjusted, cachename=cachename, + ochl=False) + + +def _quotes_historical_yahoo(ticker, date1, date2, asobject=False, + adjusted=True, cachename=None, + ochl=True): + """ Get historical data for ticker between date1 and date2. See :func:`parse_yahoo_historical` for explanation of output formats and the *asobject* and *adjusted* kwargs. - Ex: - sp = f.quotes_historical_yahoo('^GSPC', d1, d2, - asobject=True, adjusted=True) - returns = (sp.open[1:] - sp.open[:-1])/sp.open[1:] - [n,bins,patches] = hist(returns, 100) - mu = mean(returns) - sigma = std(returns) - x = normpdf(bins, mu, sigma) - plot(bins, x, color='red', lw=2) + Parameters + ---------- + ticker : str + stock ticker + + date1 : sequence of form (year, month, day), `datetime`, or `date` + start date + + date2 : sequence of form (year, month, day), `datetime`, or `date` + end date + + cachename : str or `None` + is the name of the local file cache. If None, will + default to the md5 hash or the url (which incorporates the ticker + and date range) + + ochl: bool + temporary argument to select between ochl and ohlc ordering + + + Examples + -------- + >>> sp = f.quotes_historical_yahoo('^GSPC', d1, d2, + asobject=True, adjusted=True) + >>> returns = (sp.open[1:] - sp.open[:-1])/sp.open[1:] + >>> [n,bins,patches] = hist(returns, 100) + >>> mu = mean(returns) + >>> sigma = std(returns) + >>> x = normpdf(bins, mu, sigma) + >>> plot(bins, x, color='red', lw=2) - cachename is the name of the local file cache. If None, will - default to the md5 hash or the url (which incorporates the ticker - and date range) """ # Maybe enable a warning later as part of a slow transition # to using None instead of False. @@ -236,70 +609,199 @@ def quotes_historical_yahoo(ticker, date1, date2, asobject=False, fh = fetch_historical_yahoo(ticker, date1, date2, cachename) try: - ret = parse_yahoo_historical(fh, asobject=asobject, - adjusted=adjusted) + ret = _parse_yahoo_historical(fh, asobject=asobject, + adjusted=adjusted, ochl=ochl) if len(ret) == 0: return None except IOError as exc: - warnings.warn('fh failure\n%s'%(exc.strerror[1])) + warnings.warn('fh failure\n%s' % (exc.strerror[1])) return None return ret + def plot_day_summary(ax, quotes, ticksize=3, colorup='k', colordown='r', ): + """Plots day summary + + Represent the time, open, close, high, low as a vertical line + ranging from low to high. The left tick is the open and the right + tick is the close. + + + This function has been deprecated in 1.4 in favor of + `plot_day_summary_ochl`, which maintains the original argument + order, or `plot_day_summary_ohlc`, which uses the + open-high-low-close order. This function will be removed in 1.5 + + + Parameters + ---------- + ax : `Axes` + an `Axes` instance to plot to + quotes : sequence of (time, open, close, high, low, ...) sequences + data to plot. time must be in float date format - see date2num + ticksize : int + open/close tick marker in points + colorup : color + the color of the lines where close >= open + colordown : color + the color of the lines where close < open + + Returns + ------- + lines : list + list of tuples of the lines added (one tuple per quote) """ - quotes is a sequence of (time, open, close, high, low, ...) sequences + warnings.warn(_warn_str.format(fun='plot_day_summary'), + mplDeprecation) - Represent the time, open, close, high, low as a vertical line - ranging from low to high. The left tick is the open and the right - tick is the close. + return _plot_day_summary(ax, quotes, ticksize=ticksize, + colorup=colorup, colordown=colordown, + ochl=True) - time must be in float date format - see date2num - ax : an Axes instance to plot to - ticksize : open/close tick marker in points - colorup : the color of the lines where close >= open - colordown : the color of the lines where close < open - return value is a list of lines added +def plot_day_summary_oclh(ax, quotes, ticksize=3, + colorup='k', colordown='r', + ): + """Plots day summary + + Represent the time, open, close, high, low as a vertical line + ranging from low to high. The left tick is the open and the right + tick is the close. + + + + Parameters + ---------- + ax : `Axes` + an `Axes` instance to plot to + quotes : sequence of (time, open, close, high, low, ...) sequences + data to plot. time must be in float date format - see date2num + ticksize : int + open/close tick marker in points + colorup : color + the color of the lines where close >= open + colordown : color + the color of the lines where close < open + + Returns + ------- + lines : list + list of tuples of the lines added (one tuple per quote) """ + return _plot_day_summary(ax, quotes, ticksize=ticksize, + colorup=colorup, colordown=colordown, + ochl=True) + + +def plot_day_summary_ohlc(ax, quotes, ticksize=3, + colorup='k', colordown='r', + ): + """Plots day summary + + Represent the time, open, high, low, close as a vertical line + ranging from low to high. The left tick is the open and the right + tick is the close. + + + + Parameters + ---------- + ax : `Axes` + an `Axes` instance to plot to + quotes : sequence of (time, open, high, low, close, ...) sequences + data to plot. time must be in float date format - see date2num + ticksize : int + open/close tick marker in points + colorup : color + the color of the lines where close >= open + colordown : color + the color of the lines where close < open + + Returns + ------- + lines : list + list of tuples of the lines added (one tuple per quote) + """ + return _plot_day_summary(ax, quotes, ticksize=ticksize, + colorup=colorup, colordown=colordown, + ochl=False) + +def _plot_day_summary(ax, quotes, ticksize=3, + colorup='k', colordown='r', + ochl=True + ): + """Plots day summary + + + Represent the time, open, high, low, close as a vertical line + ranging from low to high. The left tick is the open and the right + tick is the close. + + + + Parameters + ---------- + ax : `Axes` + an `Axes` instance to plot to + quotes : sequence of quote sequences + data to plot. time must be in float date format - see date2num + (time, open, high, low, close, ...) vs + (time, open, close, high, low, ...) + set by `ochl` + ticksize : int + open/close tick marker in points + colorup : color + the color of the lines where close >= open + colordown : color + the color of the lines where close < open + ochl: bool + argument to select between ochl and ohlc ordering of quotes + + Returns + ------- + lines : list + list of tuples of the lines added (one tuple per quote) + """ + # unfortunately this has a different return type than plot_day_summary2_* lines = [] for q in quotes: + if ochl: + t, open, close, high, low = q[:5] + else: + t, open, high, low, close = q[:5] + + if close >= open: + color = colorup + else: + color = colordown - t, open, close, high, low = q[:5] + vline = Line2D(xdata=(t, t), ydata=(low, high), + color=color, + antialiased=False, # no need to antialias vert lines + ) - if close>=open : color = colorup - else : color = colordown + oline = Line2D(xdata=(t, t), ydata=(open, open), + color=color, + antialiased=False, + marker=TICKLEFT, + markersize=ticksize, + ) - vline = Line2D( - xdata=(t, t), ydata=(low, high), - color=color, - antialiased=False, # no need to antialias vert lines - ) - - oline = Line2D( - xdata=(t, t), ydata=(open, open), - color=color, - antialiased=False, - marker=TICKLEFT, - markersize=ticksize, - ) - - cline = Line2D( - xdata=(t, t), ydata=(close, close), - color=color, - antialiased=False, - markersize=ticksize, - marker=TICKRIGHT) + cline = Line2D(xdata=(t, t), ydata=(close, close), + color=color, + antialiased=False, + markersize=ticksize, + marker=TICKRIGHT) lines.extend((vline, oline, cline)) ax.add_line(vline) ax.add_line(oline) ax.add_line(cline) - ax.autoscale_view() return lines @@ -309,62 +811,204 @@ def candlestick(ax, quotes, width=0.2, colorup='k', colordown='r', alpha=1.0): """ + Plot the time, open, close, high, low as a vertical line ranging + from low to high. Use a rectangular bar to represent the + open-close span. If close >= open, use colorup to color the bar, + otherwise use colordown + + + This function has been deprecated in 1.4 in favor of + `candlestick_ochl`, which maintains the original argument + order, or `candlestick_ohlc`, which uses the + open-high-low-close order. This function will be removed in 1.5 + + + Parameters + ---------- + ax : `Axes` + an Axes instance to plot to + quotes : sequence of (time, open, close, high, low, ...) sequences + As long as the first 5 elements are these values, + the record can be as long as you want (eg it may store volume). + + time must be in float days format - see date2num + + width : float + fraction of a day for the rectangle width + colorup : color + the color of the rectangle where close >= open + colordown : color + the color of the rectangle where close < open + alpha : float + the rectangle alpha level + + Returns + ------- + ret : tuple + returns (lines, patches) where lines is a list of lines + added and patches is a list of the rectangle patches added + + """ + warnings.warn(_warn_str.format(fun='candlestick'), + mplDeprecation) - quotes is a sequence of (time, open, close, high, low, ...) sequences. - As long as the first 5 elements are these values, - the record can be as long as you want (eg it may store volume). + return _candlestick(ax, quotes, width=width, colorup=colorup, + colordown=colordown, + alpha=alpha, ochl=True) - time must be in float days format - see date2num +def candlestick_ochl(ax, quotes, width=0.2, colorup='k', colordown='r', + alpha=1.0): + + """ Plot the time, open, close, high, low as a vertical line ranging from low to high. Use a rectangular bar to represent the open-close span. If close >= open, use colorup to color the bar, otherwise use colordown - ax : an Axes instance to plot to - width : fraction of a day for the rectangle width - colorup : the color of the rectangle where close >= open - colordown : the color of the rectangle where close < open - alpha : the rectangle alpha level + Parameters + ---------- + ax : `Axes` + an Axes instance to plot to + quotes : sequence of (time, open, close, high, low, ...) sequences + As long as the first 5 elements are these values, + the record can be as long as you want (eg it may store volume). + + time must be in float days format - see date2num + + width : float + fraction of a day for the rectangle width + colorup : color + the color of the rectangle where close >= open + colordown : color + the color of the rectangle where close < open + alpha : float + the rectangle alpha level + + Returns + ------- + ret : tuple + returns (lines, patches) where lines is a list of lines + added and patches is a list of the rectangle patches added + + """ + return _candlestick(ax, quotes, width=width, colorup=colorup, + colordown=colordown, + alpha=alpha, ochl=True) - return value is lines, patches where lines is a list of lines - added and patches is a list of the rectangle patches added + +def candlestick_ohlc(ax, quotes, width=0.2, colorup='k', colordown='r', + alpha=1.0): """ + Plot the time, open, high, low, close as a vertical line ranging + from low to high. Use a rectangular bar to represent the + open-close span. If close >= open, use colorup to color the bar, + otherwise use colordown + + Parameters + ---------- + ax : `Axes` + an Axes instance to plot to + quotes : sequence of (time, open, high, low, close, ...) sequences + As long as the first 5 elements are these values, + the record can be as long as you want (eg it may store volume). + + time must be in float days format - see date2num + + width : float + fraction of a day for the rectangle width + colorup : color + the color of the rectangle where close >= open + colordown : color + the color of the rectangle where close < open + alpha : float + the rectangle alpha level + + Returns + ------- + ret : tuple + returns (lines, patches) where lines is a list of lines + added and patches is a list of the rectangle patches added + + """ + return _candlestick(ax, quotes, width=width, colorup=colorup, + colordown=colordown, + alpha=alpha, ochl=False) + - OFFSET = width/2.0 +def _candlestick(ax, quotes, width=0.2, colorup='k', colordown='r', + alpha=1.0, ochl=True): + + """ + Plot the time, open, high, low, close as a vertical line ranging + from low to high. Use a rectangular bar to represent the + open-close span. If close >= open, use colorup to color the bar, + otherwise use colordown + + Parameters + ---------- + ax : `Axes` + an Axes instance to plot to + quotes : sequence of quote sequences + data to plot. time must be in float date format - see date2num + (time, open, high, low, close, ...) vs + (time, open, close, high, low, ...) + set by `ochl` + width : float + fraction of a day for the rectangle width + colorup : color + the color of the rectangle where close >= open + colordown : color + the color of the rectangle where close < open + alpha : float + the rectangle alpha level + ochl: bool + argument to select between ochl and ohlc ordering of quotes + + Returns + ------- + ret : tuple + returns (lines, patches) where lines is a list of lines + added and patches is a list of the rectangle patches added + + """ + + OFFSET = width / 2.0 lines = [] patches = [] for q in quotes: - t, open, close, high, low = q[:5] + if ochl: + t, open, close, high, low = q[:5] + else: + t, open, high, low, close = q[:5] - if close>=open : + if close >= open: color = colorup lower = open - height = close-open - else : + height = close - open + else: color = colordown lower = close - height = open-close + height = open - close vline = Line2D( xdata=(t, t), ydata=(low, high), color='k', linewidth=0.5, antialiased=True, - ) + ) rect = Rectangle( - xy = (t-OFFSET, lower), + xy=(t - OFFSET, lower), width = width, height = height, facecolor = color, edgecolor = color, - ) + ) rect.set_alpha(alpha) - lines.append(vline) patches.append(rect) ax.add_line(vline) @@ -376,85 +1020,183 @@ def candlestick(ax, quotes, width=0.2, colorup='k', colordown='r', def plot_day_summary2(ax, opens, closes, highs, lows, ticksize=4, colorup='k', colordown='r', - ): + ): + """Represent the time, open, close, high, low, as a vertical line + ranging from low to high. The left tick is the open and the right + tick is the close. + + + This function has been deprecated in 1.4 in favor of + `plot_day_summary2_ochl`, which maintains the original argument + order, or `plot_day_summary2_ohlc`, which uses the + open-high-low-close order. This function will be removed in 1.5 + + + Parameters + ---------- + ax : `Axes` + an Axes instance to plot to + opens : sequence + sequence of opening values + closes : sequence + sequence of closing values + highs : sequence + sequence of high values + lows : sequence + sequence of low values + ticksize : int + size of open and close ticks in points + colorup : color + the color of the lines where close >= open + colordown : color + the color of the lines where close < open + + Returns + ------- + ret : list + a list of lines added to the axes """ - Represent the time, open, close, high, low as a vertical line + warnings.warn(_warn_str.format(fun='plot_day_summary2'), mplDeprecation) + return plot_day_summary2_ohlc(ax, opens, highs, lows, closes, ticksize, + colorup, colordown) + + +def plot_day_summary2_ochl(ax, opens, closes, highs, lows, ticksize=4, + colorup='k', colordown='r', + ): + + """Represent the time, open, close, high, low, as a vertical line ranging from low to high. The left tick is the open and the right tick is the close. - ax : an Axes instance to plot to - ticksize : size of open and close ticks in points - colorup : the color of the lines where close >= open - colordown : the color of the lines where close < open - - return value is a list of lines added + Parameters + ---------- + ax : `Axes` + an Axes instance to plot to + opens : sequence + sequence of opening values + closes : sequence + sequence of closing values + highs : sequence + sequence of high values + lows : sequence + sequence of low values + ticksize : int + size of open and close ticks in points + colorup : color + the color of the lines where close >= open + colordown : color + the color of the lines where close < open + + Returns + ------- + ret : list + a list of lines added to the axes """ - # note this code assumes if any value open, close, low, high is + return plot_day_summary2_ohlc(ax, opens, highs, lows, closes, ticksize, + colorup, colordown) + + +def plot_day_summary2_ohlc(ax, opens, highs, lows, closes, ticksize=4, + colorup='k', colordown='r', + ): + + """Represent the time, open, high, low, close as a vertical line + ranging from low to high. The left tick is the open and the right + tick is the close. + + Parameters + ---------- + ax : `Axes` + an Axes instance to plot to + opens : sequence + sequence of opening values + highs : sequence + sequence of high values + lows : sequence + sequence of low values + closes : sequence + sequence of closing values + ticksize : int + size of open and close ticks in points + colorup : color + the color of the lines where close >= open + colordown : color + the color of the lines where close < open + + Returns + ------- + ret : list + a list of lines added to the axes + """ + # note this code assumes if any value open, high, low, close is # missing they all are missing - rangeSegments = [ ((i, low), (i, high)) for i, low, high in zip(xrange(len(lows)), lows, highs) if low != -1 ] + rangeSegments = [((i, low), (i, high)) for i, low, high in + zip(xrange(len(lows)), lows, highs) if low != -1] # the ticks will be from ticksize to 0 in points at the origin and # we'll translate these to the i, close location - openSegments = [ ((-ticksize, 0), (0, 0)) ] + openSegments = [((-ticksize, 0), (0, 0))] # the ticks will be from 0 to ticksize in points at the origin and # we'll translate these to the i, close location - closeSegments = [ ((0, 0), (ticksize, 0)) ] - + closeSegments = [((0, 0), (ticksize, 0))] - offsetsOpen = [ (i, open) for i, open in zip(xrange(len(opens)), opens) if open != -1 ] + offsetsOpen = [(i, open) for i, open in + zip(xrange(len(opens)), opens) if open != -1] - offsetsClose = [ (i, close) for i, close in zip(xrange(len(closes)), closes) if close != -1 ] + offsetsClose = [(i, close) for i, close in + zip(xrange(len(closes)), closes) if close != -1] - - scale = ax.figure.dpi * (1.0/72.0) + scale = ax.figure.dpi * (1.0 / 72.0) tickTransform = Affine2D().scale(scale, 0.0) - r,g,b = colorConverter.to_rgb(colorup) - colorup = r,g,b,1 - r,g,b = colorConverter.to_rgb(colordown) - colordown = r,g,b,1 - colord = { True : colorup, - False : colordown, - } - colors = [colord[open= open + colordown : color + the color of the lines where close < open + alpha : float + bar transparency + + Returns + ------- + ret : tuple + (lineCollection, barCollection) """ - Represent the open, close as a bar line and high low range as a - vertical line. + candlestick2_ohlc(ax, opens, highs, closes, lows, width=width, + colorup=colorup, colordown=colordown, + alpha=alpha) - ax : an Axes instance to plot to - width : the bar width in points - colorup : the color of the lines where close >= open - colordown : the color of the lines where close < open - alpha : bar transparency +def candlestick2(ax, opens, closes, highs, lows, width=4, + colorup='k', colordown='r', + alpha=0.75, + ): + """Represent the open, close as a bar line and high low range as a + vertical line. - return value is lineCollection, barCollection + This function has been deprecated in 1.4 in favor of + `candlestick2_ochl`, which maintains the original argument order, + or `candlestick2_ohlc`, which uses the open-high-low-close order. + This function will be removed in 1.5 + + + Parameters + ---------- + ax : `Axes` + an Axes instance to plot to + opens : sequence + sequence of opening values + closes : sequence + sequence of closing values + highs : sequence + sequence of high values + lows : sequence + sequence of low values + ticksize : int + size of open and close ticks in points + colorup : color + the color of the lines where close >= open + colordown : color + the color of the lines where close < open + alpha : float + bar transparency + + Returns + ------- + ret : tuple + (lineCollection, barCollection) """ + warnings.warn(_warn_str.format(fun='candlestick2'), + mplDeprecation) - # note this code assumes if any value open, close, low, high is - # missing they all are missing - - delta = width/2. - barVerts = [ ( (i-delta, open), (i-delta, close), (i+delta, close), (i+delta, open) ) for i, open, close in zip(xrange(len(opens)), opens, closes) if open != -1 and close!=-1 ] + candlestick2_ohlc(ax, opens, highs, lows, closes, width=width, + colorup=colorup, colordown=colordown, + alpha=alpha) - rangeSegments = [ ((i, low), (i, high)) for i, low, high in zip(xrange(len(lows)), lows, highs) if low != -1 ] +def candlestick2_ohlc(ax, opens, highs, lows, closes, width=4, + colorup='k', colordown='r', + alpha=0.75, + ): + """Represent the open, close as a bar line and high low range as a + vertical line. - r,g,b = colorConverter.to_rgb(colorup) - colorup = r,g,b,alpha - r,g,b = colorConverter.to_rgb(colordown) - colordown = r,g,b,alpha - colord = { True : colorup, - False : colordown, - } - colors = [colord[open= open + colordown : color + the color of the lines where close < open + alpha : float + bar transparency + + Returns + ------- + ret : tuple + (lineCollection, barCollection) + """ + # note this code assumes if any value open, low, high, close is + # missing they all are missing - assert(len(barVerts)==len(rangeSegments)) + delta = width / 2. + barVerts = [((i - delta, open), + (i - delta, close), + (i + delta, close), + (i + delta, open)) + for i, open, close in zip(xrange(len(opens)), opens, closes) + if open != -1 and close != -1] + + rangeSegments = [((i, low), (i, high)) + for i, low, high in zip(xrange(len(lows)), lows, highs) + if low != -1] + + r, g, b = colorConverter.to_rgb(colorup) + colorup = r, g, b, alpha + r, g, b = colorConverter.to_rgb(colordown) + colordown = r, g, b, alpha + colord = {True: colorup, + False: colordown, + } + colors = [colord[open < close] + for open, close in zip(opens, closes) + if open != -1 and close != -1] + + assert(len(barVerts) == len(rangeSegments)) useAA = 0, # use tuple here lw = 0.5, # and here rangeCollection = LineCollection(rangeSegments, - colors = ( (0,0,0,1), ), - linewidths = lw, + colors=((0, 0, 0, 1), ), + linewidths=lw, antialiaseds = useAA, ) - barCollection = PolyCollection(barVerts, - facecolors = colors, - edgecolors = ( (0,0,0,1), ), - antialiaseds = useAA, - linewidths = lw, + facecolors=colors, + edgecolors=((0, 0, 0, 1), ), + antialiaseds=useAA, + linewidths=lw, ) minx, maxx = 0, len(rangeSegments) - miny = min([low for low in lows if low !=-1]) + miny = min([low for low in lows if low != -1]) maxy = max([high for high in highs if high != -1]) corners = (minx, miny), (maxx, maxy) @@ -537,40 +1389,61 @@ def candlestick2(ax, opens, closes, highs, lows, width=4, ax.add_collection(rangeCollection) return rangeCollection, barCollection + def volume_overlay(ax, opens, closes, volumes, colorup='k', colordown='r', width=4, alpha=1.0): - """ - Add a volume overlay to the current axes. The opens and closes + """Add a volume overlay to the current axes. The opens and closes are used to determine the color of the bar. -1 is missing. If a value is missing on one it must be missing on all - ax : an Axes instance to plot to - width : the bar width in points - colorup : the color of the lines where close >= open - colordown : the color of the lines where close < open - alpha : bar transparency - + Parameters + ---------- + ax : `Axes` + an Axes instance to plot to + opens : sequence + a sequence of opens + closes : sequence + a sequence of closes + volumes : sequence + a sequence of volumes + width : int + the bar width in points + colorup : color + the color of the lines where close >= open + colordown : color + the color of the lines where close < open + alpha : float + bar transparency + + Returns + ------- + ret : `barCollection` + The `barrCollection` added to the axes """ - r,g,b = colorConverter.to_rgb(colorup) - colorup = r,g,b,alpha - r,g,b = colorConverter.to_rgb(colordown) - colordown = r,g,b,alpha - colord = { True : colorup, - False : colordown, - } - colors = [colord[open= open - colordown : the color of the lines where close < open - alpha : bar transparency - nb: first point is not displayed - it is used only for choosing the right color + + Parameters + ---------- + ax : `Axes` + an Axes instance to plot to + closes : sequence + a sequence of closes + volumes : sequence + a sequence of volumes + width : int + the bar width in points + colorup : color + the color of the lines where close >= open + colordown : color + the color of the lines where close < open + alpha : float + bar transparency + + Returns + ------- + ret : `barCollection` + The `barrCollection` added to the axes + """ - return volume_overlay(ax,closes[:-1],closes[1:],volumes[1:],colorup,colordown,width,alpha) + return volume_overlay(ax, closes[:-1], closes[1:], volumes[1:], + colorup, colordown, width, alpha) def volume_overlay3(ax, quotes, - colorup='k', colordown='r', - width=4, alpha=1.0): - """ - Add a volume overlay to the current axes. quotes is a list of (d, - open, close, high, low, volume) and close-open is used to + colorup='k', colordown='r', + width=4, alpha=1.0): + """Add a volume overlay to the current axes. quotes is a list of (d, + open, high, low, close, volume) and close-open is used to determine the color of the bar - kwarg - width : the bar width in points - colorup : the color of the lines where close1 >= close0 - colordown : the color of the lines where close1 < close0 - alpha : bar transparency + Parameters + ---------- + ax : `Axes` + an Axes instance to plot to + quotes : sequence of (time, open, high, low, close, ...) sequences + data to plot. time must be in float date format - see date2num + width : int + the bar width in points + colorup : color + the color of the lines where close1 >= close0 + colordown : color + the color of the lines where close1 < close0 + alpha : float + bar transparency + + Returns + ------- + ret : `barCollection` + The `barrCollection` added to the axes """ - r,g,b = colorConverter.to_rgb(colorup) - colorup = r,g,b,alpha - r,g,b = colorConverter.to_rgb(colordown) - colordown = r,g,b,alpha - colord = { True : colorup, - False : colordown, - } - - dates, opens, closes, highs, lows, volumes = zip(*quotes) - colors = [colord[close1>=close0] for close0, close1 in zip(closes[:-1], closes[1:]) if close0!=-1 and close1 !=-1] - colors.insert(0,colord[closes[0]>=opens[0]]) + r, g, b = colorConverter.to_rgb(colorup) + colorup = r, g, b, alpha + r, g, b = colorConverter.to_rgb(colordown) + colordown = r, g, b, alpha + colord = {True: colorup, + False: colordown, + } - right = width/2.0 - left = -width/2.0 + dates, opens, highs, lows, closes, volumes = zip(*quotes) + colors = [colord[close1 >= close0] + for close0, close1 in zip(closes[:-1], closes[1:]) + if close0 != -1 and close1 != -1] + colors.insert(0, colord[closes[0] >= opens[0]]) + right = width / 2.0 + left = -width / 2.0 - bars = [ ( (left, 0), (left, volume), (right, volume), (right, 0)) for d, open, close, high, low, volume in quotes] + bars = [((left, 0), (left, volume), (right, volume), (right, 0)) + for d, open, high, low, close, volume in quotes] - sx = ax.figure.dpi * (1.0/72.0) # scale for points + sx = ax.figure.dpi * (1.0 / 72.0) # scale for points sy = ax.bbox.height / ax.viewLim.height - barTransform = Affine2D().scale(sx,sy) + barTransform = Affine2D().scale(sx, sy) - dates = [d for d, open, close, high, low, volume in quotes] + dates = [d for d, open, high, low, close, volume in quotes] offsetsBars = [(d, 0) for d in dates] useAA = 0, # use tuple here lw = 0.5, # and here barCollection = PolyCollection(bars, - facecolors = colors, - edgecolors = ( (0,0,0,1), ), - antialiaseds = useAA, - linewidths = lw, - offsets = offsetsBars, - transOffset = ax.transData, + facecolors=colors, + edgecolors=((0, 0, 0, 1),), + antialiaseds=useAA, + linewidths=lw, + offsets=offsetsBars, + transOffset=ax.transData, ) barCollection.set_transform(barTransform) - - - - - minpy, maxx = (min(dates), max(dates)) miny = 0 - maxy = max([volume for d, open, close, high, low, volume in quotes]) + maxy = max([volume for d, open, high, low, close, volume in quotes]) corners = (minpy, miny), (maxx, maxy) ax.update_datalim(corners) #print 'datalim', ax.dataLim.bounds @@ -677,53 +1578,63 @@ def volume_overlay3(ax, quotes, return barCollection + def index_bar(ax, vals, facecolor='b', edgecolor='l', width=4, alpha=1.0, ): - """ - Add a bar collection graph with height vals (-1 is missing). - - ax : an Axes instance to plot to - width : the bar width in points - alpha : bar transparency - + """Add a bar collection graph with height vals (-1 is missing). + + Parameters + ---------- + ax : `Axes` + an Axes instance to plot to + vals : sequence + a sequence of values + facecolor : color + the color of the bar face + edgecolor : color + the color of the bar edges + width : int + the bar width in points + alpha : float + bar transparency + + Returns + ------- + ret : `barCollection` + The `barrCollection` added to the axes """ facecolors = (colorConverter.to_rgba(facecolor, alpha),) edgecolors = (colorConverter.to_rgba(edgecolor, alpha),) - right = width/2.0 - left = -width/2.0 + right = width / 2.0 + left = -width / 2.0 + bars = [((left, 0), (left, v), (right, v), (right, 0)) + for v in vals if v != -1] - bars = [ ( (left, 0), (left, v), (right, v), (right, 0)) for v in vals if v != -1 ] - - sx = ax.figure.dpi * (1.0/72.0) # scale for points + sx = ax.figure.dpi * (1.0 / 72.0) # scale for points sy = ax.bbox.height / ax.viewLim.height - barTransform = Affine2D().scale(sx,sy) + barTransform = Affine2D().scale(sx, sy) - offsetsBars = [ (i, 0) for i,v in enumerate(vals) if v != -1 ] + offsetsBars = [(i, 0) for i, v in enumerate(vals) if v != -1] barCollection = PolyCollection(bars, - facecolors = facecolors, - edgecolors = edgecolors, - antialiaseds = (0,), - linewidths = (0.5,), - offsets = offsetsBars, - transOffset = ax.transData, + facecolors=facecolors, + edgecolors=edgecolors, + antialiaseds=(0,), + linewidths=(0.5,), + offsets=offsetsBars, + transOffset=ax.transData, ) barCollection.set_transform(barTransform) - - - - - minpy, maxx = (0, len(offsetsBars)) miny = 0 - maxy = max([v for v in vals if v!=-1]) + maxy = max([v for v in vals if v != -1]) corners = (minpy, miny), (maxx, maxy) ax.update_datalim(corners) ax.autoscale_view()