matplotlib 子绘图问题

时间:2021-04-30 03:17:44

标签: python matplotlib

我为子绘图制作了一个代码

fig, axs = plt.subplots(2, 2, figsize = (20,10))
candlestick_ohlc(axs[0,0],df.values,width=0.6,colorup='green', colordown='red', alpha=0.5);
candlestick_ohlc(axs[0,0],df1.values,width=0.6,colorup='red', colordown='green', alpha=0.8);
date_format = mpl_dates.DateFormatter('%d %b %Y')

axs[0,0].xaxis.set_major_formatter(date_format)
axs[0,0].xaxis.set_major_formatter(date_format)

for level in levels:
  axs[0,0].hlines(level[1],xmin=df['Date'][level[0]],\
             xmax=max(df['Date']),colors='black')
fig.autofmt_xdate()

axs[1,1].plot(ichi['Close'],label = 'Close')
axs[1,0].scatter(df.index, df.Close, c = squeeze['signal'])

axs[1,1].fill_between(ichi.index, ichi['ISA_9'],ichi['ISB_26'], where = ichi['ISA_9']>ichi['ISB_26'], facecolor = 'green', alpha = 0.5)

axs[1,1].fill_between(ichi.index, ichi['ISA_9'],ichi['ISB_26'], where = ichi['ISA_9']<ichi['ISB_26'], facecolor = 'red', alpha = 0.5)
axs[1,1].legend()

我对此很满意

My subplot

但是,我想在 axs[0,1] 处再添加一个图,为此我使用了 Trendln 包来绘制支撑和阻力图

plt.figure(figsize = (20,10))
f= trendln.plot_support_resistance(hist[-100:].Close,accuracy = 10) 
plt.show()
plt.clf() #clear figure

Support resistance plot

有什么方法可以将支撑阻力图合并到我的初始图 axs[0,1]

1 个答案:

答案 0 :(得分:1)

不幸的是,阅读trendln的源代码,他们直接使用plt.plot来做任何事情,所以不容易做到这一点。您必须自己更改源代码。你可以看到源所在的位置:

>>> import trendln
>>> trendln.__file__
'/home/username/.local/lib/python3.8/site-packages/trendln/__init__.py'
>>> 

那么就可以直接将plot_support_resistance函数修改为如下。我基本上让它使用 axs 并在那里绘图而不是 plt;还有一些其他的变化要进行:

def plot_support_resistance(axs, hist, xformatter = None, numbest = 2, fromwindows = True,
                            pctbound=0.1, extmethod = METHOD_NUMDIFF, method=METHOD_NSQUREDLOGN,
                            window=125, errpct = 0.005, hough_scale=0.01, hough_prob_iter=10, sortError=False, accuracy=1):
    import matplotlib.pyplot as plt
    import matplotlib.ticker as ticker
    ret = calc_support_resistance(hist, extmethod, method, window, errpct, hough_scale, hough_prob_iter, sortError, accuracy)
    # plt.clf()
    # plt.subplot(111)

    if len(ret) == 2:
        minimaIdxs, pmin, mintrend, minwindows = ret[0]
        maximaIdxs, pmax, maxtrend, maxwindows = ret[1]
        if type(hist) is tuple and len(hist) == 2 and check_num_alike(hist[0]) and check_num_alike(hist[1]):
            len_h = len(hist[0])
            min_h, max_h = min(min(hist[0]), min(hist[1])), max(max(hist[0]), max(hist[1]))
            disp = [(hist[0], minimaIdxs, pmin, 'yo', 'Avg. Support', 'y--'), (hist[1], maximaIdxs, pmax, 'bo', 'Avg. Resistance', 'b--')]
            dispwin = [(hist[0], minwindows, 'Support', 'g--'), (hist[1], maxwindows, 'Resistance', 'r--')]
            disptrend = [(hist[0], mintrend, 'Support', 'g--'), (hist[1], maxtrend, 'Resistance', 'r--')]
            axs.plot(range(len_h), hist[0], 'k--', label='Low Price')
            axs.plot(range(len_h), hist[1], 'm--', label='High Price')
        else:
            len_h = len(hist)
            min_h, max_h = min(hist), max(hist)
            disp = [(hist, minimaIdxs, pmin, 'yo', 'Avg. Support', 'y--'), (hist, maximaIdxs, pmax, 'bo', 'Avg. Resistance', 'b--')]
            dispwin = [(hist, minwindows, 'Support', 'g--'), (hist, maxwindows, 'Resistance', 'r--')]
            disptrend = [(hist, mintrend, 'Support', 'g--'), (hist, maxtrend, 'Resistance', 'r--')]
            axs.plot(range(len_h), hist, 'k--', label='Close Price')
    else:
        minimaIdxs, pmin, mintrend, minwindows = ([], [], [], []) if hist[0] is None else ret
        maximaIdxs, pmax, maxtrend, maxwindows = ([], [], [], []) if hist[1] is None else ret
        len_h = len(hist[1 if hist[0] is None else 0])
        min_h, max_h = min(hist[1 if hist[0] is None else 0]), max(hist[1 if hist[0] is None else 0])
        disp = [(hist[1], maximaIdxs, pmax, 'bo', 'Avg. Resistance', 'b--') if hist[0] is None else (hist[0], minimaIdxs, pmin, 'yo', 'Avg. Support', 'y--')]
        dispwin = [(hist[1], maxwindows, 'Resistance', 'r--') if hist[0] is None else (hist[0], minwindows, 'Support', 'g--')]
        disptrend = [(hist[1], maxtrend, 'Resistance', 'r--') if hist[0] is None else (hist[0], mintrend, 'Support', 'g--')]
        axs.plot(range(len_h), hist[1 if hist[0] is None else 0], 'k--', label= ('High' if hist[0] is None else 'Low') + ' Price')
    for h, idxs, pm, clrp, lbl, clrl in disp:
        axs.plot(idxs, [h[x] for x in idxs], clrp)
        axs.plot([0, len_h-1],[pm[1],pm[0] * (len_h-1) + pm[1]],clrl, label=lbl)
    def add_trend(h, trend, lbl, clr, bFirst):
        for ln in trend[:numbest]:
            maxx = ln[0][-1]+1
            while maxx < len_h:
                ypred = ln[1][0] * maxx + ln[1][1]
                if (h[maxx] > ypred and h[maxx-1] < ypred or h[maxx] < ypred and h[maxx-1] > ypred or
                    ypred > max_h + (max_h-min_h)*pctbound or ypred < min_h - (max_h-min_h)*pctbound): break
                maxx += 1
            x_vals = np.array((ln[0][0], maxx)) # plt.gca().get_xlim())
            y_vals = ln[1][0] * x_vals + ln[1][1]
            if bFirst:
                axs.plot([ln[0][0], maxx], y_vals, clr, label=lbl)
                bFirst = False
            else: axs.plot([ln[0][0], maxx], y_vals, clr)
        return bFirst
    if fromwindows:
        for h, windows, lbl, clr in dispwin:
            bFirst = True
            for trend in windows:
                bFirst = add_trend(h, trend, lbl, clr, bFirst)
    else:
        for h, trend, lbl, clr in disptrend:
            add_trend(h, trend, lbl, clr, True)
    # axs.title('Prices with Support/Resistance Trend Lines')
    #axs.xlabel('Date')
    #axs.ylabel('Price')
    axs.legend()
    #plt.gca()
    axs.xaxis.set_major_locator(ticker.MaxNLocator(6))
    #plt.gca().xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m'))
    #if not xformatter is None: plt.gca().xaxis.set_major_formatter(xformatter)
    #plt.setp(plt.gca().get_xticklabels(), rotation=30, ha='right')
    #plt.gca().set_position([0, 0, 1, 1])
    #plt.savefig(os.path.join(curdir, 'data', 'suppres.svg'), format='svg', bbox_inches = 'tight')
    #plt.show()
    return None#plt.gcf()

既然已经处理好了,您可以传递其中一个轴来绘制东西:

import matplotlib.pyplot as plt
import trendln
import yfinance as yf

fig, axs = plt.subplots(2, 2, figsize = (20,10))
axs[0, 1].plot([0, 1], [3, 4])

tick = yf.Ticker('^GSPC') # S&P500
hist = tick.history(period="max", rounding=True)

f = trendln.plot_support_resistance(axs[0, 0], hist[-1000:].Close, accuracy = 2)

plt.show()

我得到: enter image description here

我希望这会有所帮助。您可能正在寻找另一种选择,但由于他们使用硬编码,这并不容易。我也试过复制plt绘制的轴而不是修改源代码,但没有用。