Python:Plotlyでアニメーショングラフを作成する

Posted on February 8th, 2019Updated on April 7th, 2019
Python:Plotlyでアニメーショングラフを作成する

※ この記事は最終更新日から5年以上が経過しています。

どんな記事

この記事では、以下の手順とコードをご紹介しています。

  • 3DのSurfaceグラフのアニメーション
  • Contour(等高線)グラフのアニメーション

グラフにするのは「破産の確率」

バルサラの破産確率表を算出し、グラフ化していきます。「『破産の確率』を算出する方法とコード」については別途記事を書いているので、そちらをご覧ください。

破産確率表は、以下のコードで算出しています。

破産確率表を算出
def make_dict_ruin( win_range ,rr_range ,risk_rate_range ,funds ,ruin_line ,rate_amount='amount') :
    dict_ruin = { 'index' : rr_range
                , 'columns' : [ f'{ win * 100 }' for win in win_range] }
    for risk_rate in risk_rate_range :
        raw = pd.DataFrame()
        for win in win_range :
            for rr in rr_range :
                if rate_amount=='rate' :
                    ruin_rate = ruin_fixed_rate( win ,rr ,risk_rate ,funds ,ruin_line ).calc()
                elif rate_amount=='amount' :
                    ruin_rate = ruin_fixed_amount( win ,rr ,risk_rate ).calc()
                raw.loc[ rr ,f'{ win :.0%}' ] = f'{ round( ruin_rate * 100 ,2 ) }'
        dict_ruin[ risk_rate ] = raw.T.as_matrix()
    return dict_ruin

if __name__=="__main__" :
    win_range = np.arange(0.3 ,0.62 ,0.02)
    rr_range = np.arange(0.4 ,3.1 ,0.1)
    risk_rate_range = np.arange(0.02 ,0.62 ,0.02)
    funds = 1000000
    ruin_line = 200000

    dict_ruin = make_dict_ruin( win_range ,rr_range ,risk_rate_range ,funds ,ruin_line ,rate_amount='rate')

3DのSurfaceグラフのアニメーション

まずは、グラフを作成するコードを作成。

SurfaceGraph
def make_surface_graph( dict_ruin ,risk_rate_range ,graph_title ) :

    sliders = [dict(
          steps = [dict( method = 'animate'
                       , args = [ [ f'{ risk_rate :.0%}' ]
                                , dict( mode = 'immediate'
                                      , frame = dict( duration=100 ,redraw=False )
                                      , transition = dict( duration=0 ) ) ]
                       , label=f'{ risk_rate :.0%}' ) for risk_rate in risk_rate_range ]
        , transition = dict( duration = 0 )
        , x = 0
        , y = 0
        , currentvalue = dict( font = dict(size=12)
                             , prefix = ''
                             , visible = True
                             , xanchor = 'center' )
        , len=1.0 )]

    updatemenus = [dict(
          type = 'buttons'
        , showactive = False
        , y = 1
        , x = -0.05
        , xanchor = 'right'
        , yanchor = 'top'
        , pad = dict( t=0, r=10 )
        , buttons = [dict(
              label = 'Play'
            , method = 'animate'
            , args = [ None
                     , dict( frame = dict( duration=100 , redraw=True )
                           , transition = dict( duration=0 )
                           , fromcurrent = True
                           , mode = 'immediate' )] )] )]

    layout = go.Layout( title         = graph_title
                      , autosize      = False
                      , paper_bgcolor = "#000"
                      , width         = 1000
                      , height        = 800
                      , scene = dict(
                            aspectmode = "manual"
                          , aspectratio = dict(x=1 ,y=1 ,z=0.5)
                          , xaxis = dict(color="#fff" ,linecolor="#fff" ,gridcolor="#eee" ,title="リスクリワード比率")
                          , yaxis = dict(color="#fff" ,linecolor="#fff" ,gridcolor="#eee" ,title="勝率(%)")
                          , zaxis = dict(color="#fff" ,linecolor="#fff" ,gridcolor="#eee" ,range=[-1,101] ,title="破産の確率(%)")
                          , camera = dict(eye=dict(x=1.5 ,y=.9 ,z=.7)) )
                      , font = dict(color="#fff")
                      , updatemenus = updatemenus
                      , sliders = sliders )

    z1 = dict_ruin
    data = [ go.Surface( z = z1[ 0.02 ]
                       , y = z1['columns']
                       , x = z1['index']
                       , cmin=0 ,cmax=100
                       , colorscale = "Jet"
                       , colorbar   = dict(lenmode='fraction' ,len=0.5 ,x=1 ,y=0.3 )
                       , contours   = dict(x=dict(color="#fff") ,y=dict(color="#fff") ,z=dict(color="#fff")) ) ]

    frames = []
    for risk_rate in risk_rate_range :
        frames.append( dict( data = [ go.Surface( z = z1[ risk_rate ]
                                                , y = z1['columns']
                                                , x = z1['index'] ) ]
                           , name = f'{ risk_rate :.0%}' ) )

    enable_plotly_in_cell()
    fig = dict( data=data ,layout=layout ,frames=frames )
    plotly.offline.iplot( fig )

定額の「破産の確率」

定額の「破産の確率」
if __name__=="__main__" :

    graph_title = '定額の「破産の確率」'
    make_surface_graph( dict_ruin ,risk_rate_range ,graph_title )
定額の「破産確率表」plotly surface graph risk of ruin probability fix amount

定率の「破産の確率」

定率の「破産の確率」
if __name__=="__main__" :

    graph_title = '定率の「破産の確率」、元金100万円、破産の基準:20万円'
    make_surface_graph( dict_ruin ,risk_rate_range ,graph_title )

定率の方がどんどん「『破産の確率』のエリア」が広がっていますね。

定率の「破産確率表」plotly surface graph risk of ruin probability fix rate

Contour(等高線)グラフのアニメーション

同じく、グラフを作成するコードを作成。

Contour(等高線)グラフ
def make_contour_graph( dict_ruin ,risk_rate_range ,graph_title ) :

    sliders = [dict(
          steps = [dict( method = 'animate'
                       , args = [ [ f'{ risk_rate :.0%}' ]
                                , dict( mode = 'immediate'
                                      , frame = dict( duration=100 ,redraw=False )
                                      , transition = dict( duration=0 ) )
                                ]
                       , label=f'{ risk_rate :.0%}' ) for risk_rate in risk_rate_range ]
        , transition = dict( duration = 0 )
        , x = 0
        , y = -0.15
        , currentvalue = dict( font = dict( size=16 )
                             , prefix = '損失の許容: '
                             , visible = True
                             , xanchor = 'center' )
        , len=1.0 )]

    updatemenus = [dict(
          type = 'buttons'
        , showactive = False
        , y = 1
        , x = -0.1
        , xanchor = 'right'
        , yanchor = 'top'
        , pad = dict( t=0, r=10 )
        , buttons = [dict(
              label = 'Play'
            , method = 'animate'
            , args = [ None
                     , dict( frame = dict( duration=100 , redraw=True )
                           , transition = dict( duration=0 )
                           , fromcurrent = True
                           , mode = 'immediate' )]
        )] )]

    layout = go.Layout( title       = graph_title
                      , autosize    = False
                      , width       = 1000
                      , height      = 800
                      , xaxis       = dict( title="リスクリワード比率" )
                      , yaxis       = dict( title="勝率(%)" )
                      , font        = dict( size=16 )
                      , updatemenus = updatemenus
                      , sliders     = sliders )

    z1 = dict_ruin
    data = [ go.Contour( z = z1[ 0.02 ]
                       , y = z1['columns']
                       , x = z1['index']
                       , zmin=0 ,zmax=100
                       , colorscale = "Jet" ) ]

    frames = []
    for risk_rate in risk_rate_range :
        frames.append( dict( data = [ go.Contour( z = z1[ risk_rate ]
                                                , y = z1['columns']
                                                , x = z1['index'] ) ]
                           , name = f'{ risk_rate :.0%}' ) )

    enable_plotly_in_cell()
    fig = dict( data=data ,layout=layout ,frames=frames )
    plotly.offline.iplot( fig )

定額の「破産の確率」

定額の「破産の確率」
if __name__=="__main__" :

    graph_title = '定額の「破産の確率」'
    make_contour_graph( dict_ruin ,risk_rate_range ,graph_title )
定額の「破産確率表」plotly contour graph risk of ruin probability fix amount

定率の「破産の確率」

定率の「破産の確率」
if __name__=="__main__" :

    graph_title = '定率の「破産の確率」、元金100万円、破産の基準:20万円'
    make_contour_graph( dict_ruin ,risk_rate_range ,graph_title )
定率の「破産確率表」plotly contour graph risk of ruin probability fix rate

開発を承っています

  • Pineスクリプト(インジケーターやストラテジー)
  • Google Apps Script
  • Python
  • MQL4

などの開発を承っています。とくに投資関連が得意です。過去の事例は「実績ページ(不定期更新)」でご確認ください。ご相談は「お問い合わせ」からお願いします。

yuya takahashi

タカハシ / 11年目の兼業投資家

投資やプログラミング、動画コンテンツの撮影・制作・編集などが得意。更新のお知らせは、LINE、メールで行っています。

このブログと筆者についてご質問はこちら

  • 記事をシェア
© Investment Tech Hack 2023.