numpy 带有JSON文件的Matplotlib

mlmc2os5  于 2022-11-10  发布在  其他
关注(0)|答案(2)|浏览(96)

我正在尝试组合两个代码源码,但没有效果。我使用的是默认的finance2.py matplotlib示例(下面列出)和json文件(也在下面列出)。代码的“finance.fetch_History_Yahoo”部分通过Yahoo从.csv中提取数据,并将其放入Numy数组中。问题是,我不需要转换Yahoo的数据,我需要以matplotlib库可读的方式转换JSON数据。
Finance2.py:

import datetime
import numpy as np
import matplotlib.colors as colors
import matplotlib.finance as finance
import matplotlib.dates as mdates
import matplotlib.ticker as mticker
import matplotlib.mlab as mlab
import matplotlib.pyplot as plt
import matplotlib.font_manager as font_manager
import json #to load json libraries for json data

startdate = datetime.date(2006,1,1)
today = enddate = datetime.date.today()
ticker = 'SPY'

fh = finance.fetch_historical_yahoo(ticker, startdate, enddate) #would like this call to be json

# a numpy record array with fields: date, open, high, low, close, volume, adj_close)

r = mlab.csv2rec(fh); fh.close()
r.sort()

def moving_average(x, n, type='simple'):
    """
    compute an n period moving average.

    type is 'simple' | 'exponential'

    """
    x = np.asarray(x)
    if type=='simple':
        weights = np.ones(n)
    else:
        weights = np.exp(np.linspace(-1., 0., n))

    weights /= weights.sum()

    a =  np.convolve(x, weights, mode='full')[:len(x)]
    a[:n] = a[n]
    return a

def relative_strength(prices, n=14):
    """
    compute the n period relative strength indicator
    http://stockcharts.com/school/doku.php?id=chart_school:glossary_r#relativestrengthindex
    http://www.investopedia.com/terms/r/rsi.asp
    """

    deltas = np.diff(prices)
    seed = deltas[:n+1]
    up = seed[seed>=0].sum()/n
    down = -seed[seed<0].sum()/n
    rs = up/down
    rsi = np.zeros_like(prices)
    rsi[:n] = 100. - 100./(1.+rs)

    for i in range(n, len(prices)):
        delta = deltas[i-1] # cause the diff is 1 shorter

        if delta>0:
            upval = delta
            downval = 0.
        else:
            upval = 0.
            downval = -delta

        up = (up*(n-1) + upval)/n
        down = (down*(n-1) + downval)/n

        rs = up/down
        rsi[i] = 100. - 100./(1.+rs)

    return rsi

def moving_average_convergence(x, nslow=26, nfast=12):
    """
    compute the MACD (Moving Average Convergence/Divergence) using a fast and slow exponential moving avg'
    return value is emaslow, emafast, macd which are len(x) arrays
    """
    emaslow = moving_average(x, nslow, type='exponential')
    emafast = moving_average(x, nfast, type='exponential')
    return emaslow, emafast, emafast - emaslow

plt.rc('axes', grid=True)
plt.rc('grid', color='0.75', linestyle='-', linewidth=0.5)

textsize = 9
left, width = 0.1, 0.8
rect1 = [left, 0.7, width, 0.2]
rect2 = [left, 0.3, width, 0.4]
rect3 = [left, 0.1, width, 0.2]

fig = plt.figure(facecolor='white')
axescolor  = '#f6f6f6'  # the axes background color

ax1 = fig.add_axes(rect1, axisbg=axescolor)  #left, bottom, width, height
ax2 = fig.add_axes(rect2, axisbg=axescolor, sharex=ax1)
ax2t = ax2.twinx()
ax3  = fig.add_axes(rect3, axisbg=axescolor, sharex=ax1)

### plot the relative strength indicator

prices = r.adj_close
rsi = relative_strength(prices)
fillcolor = 'darkgoldenrod'

ax1.plot(r.date, rsi, color=fillcolor)
ax1.axhline(70, color=fillcolor)
ax1.axhline(30, color=fillcolor)
ax1.fill_between(r.date, rsi, 70, where=(rsi>=70), facecolor=fillcolor, edgecolor=fillcolor)
ax1.fill_between(r.date, rsi, 30, where=(rsi<=30), facecolor=fillcolor, edgecolor=fillcolor)
ax1.text(0.6, 0.9, '>70 = overbought', va='top', transform=ax1.transAxes, fontsize=textsize)
ax1.text(0.6, 0.1, '<30 = oversold', transform=ax1.transAxes, fontsize=textsize)
ax1.set_ylim(0, 100)
ax1.set_yticks([30,70])
ax1.text(0.025, 0.95, 'RSI (14)', va='top', transform=ax1.transAxes, fontsize=textsize)
ax1.set_title('%s daily'%ticker)

### plot the price and volume data

dx = r.adj_close - r.close
low = r.low + dx
high = r.high + dx

deltas = np.zeros_like(prices)
deltas[1:] = np.diff(prices)
up = deltas>0
ax2.vlines(r.date[up], low[up], high[up], color='black', label='_nolegend_')
ax2.vlines(r.date[~up], low[~up], high[~up], color='black', label='_nolegend_')
ma20 = moving_average(prices, 20, type='simple')
ma200 = moving_average(prices, 200, type='simple')

linema20, = ax2.plot(r.date, ma20, color='blue', lw=2, label='MA (20)')
linema200, = ax2.plot(r.date, ma200, color='red', lw=2, label='MA (200)')

last = r[-1]
s = '%s O:%1.2f H:%1.2f L:%1.2f C:%1.2f, V:%1.1fM Chg:%+1.2f' % (
    today.strftime('%d-%b-%Y'),
    last.open, last.high,
    last.low, last.close,
    last.volume*1e-6,
    last.close-last.open )
t4 = ax2.text(0.3, 0.9, s, transform=ax2.transAxes, fontsize=textsize)

props = font_manager.FontProperties(size=10)
leg = ax2.legend(loc='center left', shadow=True, fancybox=True, prop=props)
leg.get_frame().set_alpha(0.5)

volume = (r.close*r.volume)/1e6  # dollar volume in millions
vmax = volume.max()
poly = ax2t.fill_between(r.date, volume, 0, label='Volume', facecolor=fillcolor, edgecolor=fillcolor)
ax2t.set_ylim(0, 5*vmax)
ax2t.set_yticks([])

### compute the MACD indicator

fillcolor = 'darkslategrey'
nslow = 26
nfast = 12
nema = 9
emaslow, emafast, macd = moving_average_convergence(prices, nslow=nslow, nfast=nfast)
ema9 = moving_average(macd, nema, type='exponential')
ax3.plot(r.date, macd, color='black', lw=2)
ax3.plot(r.date, ema9, color='blue', lw=1)
ax3.fill_between(r.date, macd-ema9, 0, alpha=0.5, facecolor=fillcolor, edgecolor=fillcolor)

ax3.text(0.025, 0.95, 'MACD (%d, %d, %d)'%(nfast, nslow, nema), va='top',
         transform=ax3.transAxes, fontsize=textsize)

# ax3.set_yticks([])

# turn off upper axis tick labels, rotate the lower ones, etc

for ax in ax1, ax2, ax2t, ax3:
    if ax!=ax3:
        for label in ax.get_xticklabels():
            label.set_visible(False)
    else:
        for label in ax.get_xticklabels():
            label.set_rotation(30)
            label.set_horizontalalignment('right')

    ax.fmt_xdata = mdates.DateFormatter('%Y-%m-%d')

class MyLocator(mticker.MaxNLocator):
    def __init__(self, *args,**kwargs):
        mticker.MaxNLocator.__init__(self, *args,**kwargs)

    def __call__(self, *args,**kwargs):
        return mticker.MaxNLocator.__call__(self, *args,**kwargs)

# at most 5 ticks, pruning the upper and lower so they don't overlap

# with other ticks

# ax2.yaxis.set_major_locator(mticker.MaxNLocator(5, prune='both'))

# ax3.yaxis.set_major_locator(mticker.MaxNLocator(5, prune='both'))

ax2.yaxis.set_major_locator(MyLocator(5, prune='both'))
ax3.yaxis.set_major_locator(MyLocator(5, prune='both'))

plt.show()

.json文件:

{
        "instrument" : "EUR_USD",
        "granularity" : "D",
        "candles" : [
                {
                        "time" : "2014-02-17T22:00:00Z",
                        "openMid" : 1.259445,
                        "highMid" : 1.259955,
                        "lowMid" : 1.251825,
                        "closeMid" : 1.257955,
                        "volume" : 61184,
                        "complete" : true
                },
                {
                        "time" : "2014-02-18T22:00:00Z",
                        "openMid" : 1.257975,
                        "highMid" : 1.259955,
                        "lowMid" : 1.251825,
                        "closeMid" : 1.252945,
                        "volume" : 67528,
                        "complete" : false
                }
        ]
}

我甚至不是在寻找一个确切的答案,在这个时间点上,即使是一个正确的方向也会非常有帮助。
提前谢谢你

8yoxcaq7

8yoxcaq71#

这只是一个部分答案--它展示了如何将json解压到一个行列表(ROW_WISE)或列列表(COLWISE)中。

import json
import numpy as np

# json embedded here, but could be read in from text file

json_string = """{
        "instrument" : "EUR_USD",
        "granularity" : "D",
        "candles" : [
                {
                        "time" : "2014-02-17T22:00:00Z",
                        "openMid" : 1.259445,
                        "highMid" : 1.259955,
                        "lowMid" : 1.251825,
                        "closeMid" : 1.257955,
                        "volume" : 61184,
                        "complete" : true
                },
                {
                        "time" : "2014-02-18T22:00:00Z",
                        "openMid" : 1.257975,
                        "highMid" : 1.259955,
                        "lowMid" : 1.251825,
                        "closeMid" : 1.252945,
                        "volume" : 67528,
                        "complete" : false
                }
        ]
       }"""

candles = json.loads(json_string)['candles']
col_heads = ['time', 'openMid', 'highMid', 'lowMid', 'closeMid', 'volume']
f = lambda c: [c[col] for col in col_heads]
row_wise = [col_heads[:]]
row_wise.extend([f(candle) for candle in candles])
for row in row_wise: print row
print
col_wise = zip(*row_wise)
for col in col_wise: print col

剩下的就是构造一个数字数组:这就是mlab.csv2rec()所产生的结果。这是留给麻木大师的练习(我不是!)

1bqhqjot

1bqhqjot2#

你可以用Pandas来更简洁地解决这个问题。以下是解决您的问题的相关信息。对不起,我没有时间根据您的特定用例自定义所有代码。让我知道,如果你再次访问这个,并希望我。
来自the docs

>>> data = [{'state': 'Florida',
...          'shortname': 'FL',
...          'info': {
...               'governor': 'Rick Scott'
...          },
...          'counties': [{'name': 'Dade', 'population': 12345},
...                      {'name': 'Broward', 'population': 40000},
...                      {'name': 'Palm Beach', 'population': 60000}]},
...         {'state': 'Ohio',
...          'shortname': 'OH',
...          'info': {
...               'governor': 'John Kasich'
...          },
...          'counties': [{'name': 'Summit', 'population': 1234},
...                       {'name': 'Cuyahoga', 'population': 1337}]}]
>>> from pandas.io.json import json_normalize
>>> result = json_normalize(data, 'counties', ['state', 'shortname',
...                                           ['info', 'governor']])
>>> result
         name  population info.governor    state shortname
0        Dade       12345    Rick Scott  Florida        FL
1     Broward       40000    Rick Scott  Florida        FL
2  Palm Beach       60000    Rick Scott  Florida        FL
3      Summit        1234   John Kasich     Ohio        OH
4    Cuyahoga        1337   John Kasich     Ohio        OH

现在您可以使用pandas dataframe to visualize the data

In [1]: import matplotlib.pyplot as plt

In [2]: ts = pandas.Series(np.random.randn(1000), index=pd.date_range('1/1/2000', periods=1000))

In [3]: ts = ts.cumsum()

In [4]: ts.plot()
Out[4]: <matplotlib.axes._subplots.AxesSubplot at 0x1120939d0>

相关问题