plotly,python,在其他子图上绘制直方图?

plotly,python, plot histogram over other subplot?

数据是时间序列,我设想了几个子图,其中一些与其他子图重叠,试图巩固我最喜欢的技术指标。 关于直方图,我想实现这样的目标:

我怎样才能正确地做到这一点?

已尝试:


fig = make_subplots(
    rows=3,
    cols=1,
    shared_xaxes=False,
    vertical_spacing=0,
    #subplot_titles=('candles','volume','atr')
    row_width=[.3,.5,1],
    specs=[
        [{'secondary_y':False}],
        [{'secondary_y':False}],
        [{'secondary_y':True}]
    ]

)

candle = go.Candlestick(
        x=df.date,
        open=df.open,
        high=df.high,
        low=df.low,
        close=df.close,
        name='Candles',
        
        increasing_line_color='#0ebc6e', 
        decreasing_line_color='#e8482c',
    
        #increasing_line_color='green',
        #decreasing_line_color='gray',
        line={'width': 1},
        hoverlabel={
            'font':{
                'color':'white',
                'family':'Open Sans',
                'size':15
            }
        },
)


vol_hist = go.Histogram(
    x=df.volume,
    y=df.close,
    orientation='h',
    name='vol hist',
    nbinsx=len(df.volume),
    nbinsy=len(df.close),
    hovertemplate=[],
    marker={
        'color':'steelblue'
    },
)

bb_hi = go.Scatter(
    x=df.date,
    y=df.bb_high,
    name='bollinger_high',
    line={'color':'orange','width':1},
    hovertemplate=[],
)

bb_low = go.Scatter(
    x=df.date,
    y=df.bb_low,
    name='bollinger_low',
    line={'color':'orange','width':1},
    hovertemplate=[],
)

vol = go.Bar(
    x=df.date,
    y=df.volume,
    name='Volume',
    marker_color='steelblue',
)

atr = go.Scatter(
    x=df.date,
    y=df.atr,
    name='ATR',
    line={'color':'steelblue','width':1}
)

fig.add_trace(candle,row=1,col=1)
fig.add_trace(vol_hist,row=1,col=1)
#fig.add_trace(bb_hi,row=1,col=1)
#fig.add_trace(bb_low,row=1,col=1)
fig.add_trace(atr,row=3,col=1)
fig.add_trace(vol,row=2,col=1)
#fig.add_trace(anime)

我首先使用 x 轴的两个轴叠加了烛台、交易量和收盘价的直方图,因为它不能分层完成。这可以通过参考this example来实现。其次,我添加了成交量条形图,然后是布林带,最后是 EMA。这是一步步输出fig.data,检查内容,修改的结果。剩下的任务是显示交易量和 EMA 的 x 轴。这是我能做到的。

import plotly.graph_objects as go
from plotly.subplots import make_subplots
import pandas as pd
import numpy as np
import yfinance as yf

df = yf.download("AAPL", start="2021-01-01", end="2021-12-01")
df.reset_index(inplace=True)
df.columns = ['date', 'open', 'high', 'low', 'close', 'adj close', 'volume']
df['ma'] = df['close'].rolling(25).mean()
df['sigma'] = df['close'].rolling(25).std()
df['bb_high'] = df['ma'] + df['sigma'] * 2
df['bb_low'] = df['ma'] - df['sigma'] * 2

fig = make_subplots(rows=3, cols=1, 
                    vertical_spacing=0.025, 
                    row_heights=[0.6,0.20,0.20],
                    shared_xaxes=False,
                    specs=[[{"secondary_y": True}],[{"secondary_y": False}],[{"secondary_y": False}]])

fig.add_trace(
    go.Histogram(
        x=df.volume,
        y=df.close,
        orientation='h',
        name='vol hist',
        nbinsx=len(df.volume),
        nbinsy=len(df.close),
        hovertemplate=[],
        opacity=0.4,
        marker={
            'color':'steelblue'
        },
), secondary_y=True)

fig.add_trace(
    go.Candlestick(
        x=df.date,
        open=df.open,
        high=df.high,
        low=df.low,
        close=df.close,
        name='Candles',
        increasing_line_color='#0ebc6e', 
        decreasing_line_color='#e8482c',
        line={'width': 1},
        hoverlabel={
            'font':{
                'color':'white',
                'family':'Open Sans',
                'size':15
            }
        },
), secondary_y=True)

fig.add_trace(
    go.Scatter(
        x=df.date, 
        y=df.bb_high,
        name='bollinger_high',
        line={'color':'orange','width':1},
        hovertemplate=[],
), secondary_y=False)

fig.add_trace(
    go.Scatter(
        x=df.date,
        y=df.bb_low,
        name='bollinger_low',
        line={'color':'orange','width':1},
        hovertemplate=[],
), secondary_y=False)

fig.add_trace(
    go.Bar(
        x=df.date,
        y=df.volume,
        name='Volume',
        marker_color='steelblue',
), secondary_y=False, row=2, col=1)

fig.add_trace(
    go.Scatter(
        x=df.date,
        y=df.close.ewm(26).mean(),
        name='EMA',
        line={'color':'steelblue','width':2}
), secondary_y=False, row=3, col=1)


fig.update_layout(xaxis2={'anchor': 'y', 'overlaying': 'x', 'side': 'top', 'autorange':'reversed'})
fig.data[0].update(xaxis='x2')
fig.update_layout(yaxis={'tickvals': np.arange(120,170,10)})
fig.data[4].update(xaxis='x')
fig.data[5].update(xaxis='x')
fig.update_xaxes(rangeslider_visible=False, showticklabels=True, row=1, col=1)
fig.update_layout(autosize=False, width=1000, height=800)
fig.show()