2016-08-24 12 views
1

私はJupyterノートブックでFoliumとBokehを併用しています。私はデータフレームをループしており、各行はFoliumマップ上にマーカーを挿入し、別のデータフレームからデータを取り出し、そのデータからBokehチャートを作成し、BokehチャートをFoliumマップポップアップに埋め込みますIFrame。コードは次のとおりです。Folium + Bokeh:パフォーマンスが低く、メモリが大量に使用されています

map = folium.Map(location=[36.710021, 35.086146],zoom_start=6) 

for i in range (0,len(duty_station_totals)): 

    popup_table = station_dept_totals.loc[station_dept_totals['Duty Station'] == duty_station_totals.iloc[i,0]] 

    chart = Bar(popup_table,label=CatAttr(columns=['Department/Program'],sort=False),values='dept_totals', 
       title=duty_station_totals.iloc[i,0] + ' Staff',xlabel='Department/Program',ylabel='Staff',plot_width=350,plot_height=350) 

    hover = HoverTool(point_policy='follow_mouse') 
    hover.tooltips=[('Staff','@height'),('Department/Program','@{Department/Program}'),('Duty Station',duty_station_totals.iloc[i,0])] 
    chart.add_tools(hover) 

    html = file_html(chart, INLINE, "my plot") 

    iframe = folium.element.IFrame(html=html, width=400, height=400) 

    popup = folium.Popup(iframe, max_width=400) 

    marker = folium.CircleMarker(duty_station_totals.iloc[i,2], 
           radius=duty_station_totals.iloc[i,1] * 150, 
           color=duty_station_totals.iloc[i,3], 
           fill_color=duty_station_totals.iloc[i,3]) 

    marker.add_to(map) 

    folium.Marker(duty_station_totals.iloc[i,2],icon=folium.Icon(color='black',icon_color=duty_station_totals.iloc[i,3]),popup=popup).add_to(map) 


map 

このループは非常にゆっくり実行され、ループの実行ごとに関連するPython 3.5プロセスのメモリ使用量に200MB!実際には、ループを数回実行した後、私のマックブック全体がクロールまで減速しています。マウスでさえ遅れています。関連する地図は、スクロールしたりズームしたりするときにも非常に時間がかかり、ポップアップが開くのが遅くなります。場合は明らかではない、私は非常にPythonの分析とWebの視覚化の世界には非常に新しいので、多分ここでは非常に非効率的な明確に何かがあります。

私はこれがなぜで、Bokehチャートを地図のポップアップに表示させる方が良いのだろうかと思います。私が行ったいくつかの基本的な実験から、問題がBarへの呼び出しであるようには思われません。file_htmlへの呼び出しを含めると、メモリ使用量が急上昇しており、folium.element.IFrameへの呼び出しが追加されると悪化します。同じコードを再実行するとメモリ使用量が増えるため、何らかのメモリリークが発生しているようです。

もっと効果的な方法で、同じ効果を達成する方法(フォルウムのマーカーをクリックするとBokeh図表が開きます)についてのアイデアがあれば、本当にありがとう!いくつかの実験

私はステップバイループステップを介して実行し、より多くのステップがしようとすると、この問題を駆動しているコードのどの部分に分離することで追加されるメモリ使用量の変化を観察してきた以下の

を更新。 Bokeh側では、最大の犯人はfile_html()の呼び出しであるようです - このステップでループを実行すると、関連するpython 3.5プロセスに約5MBのメモリ使用量が追加されます(ループは18個のチャートを作成しています) bokeh.io.curdoc().clear()

しかし、大きな問題は、フォリアムによって推進されているようです。 Bokehで生成されたHTMLとIFramesにリンクされたマップマーカーでFolium IFrameを作成することを含むループ全体を実行すると、実行ごとにPythonプロセスのメモリ使用量が25〜30MB増加します。

だから、私はこれがフォリアムの疑問をより深刻にしていると思います。なぜこの構造はメモリを大量に消費しているのですか?ちなみに、結果のFoliumマップをmap.save('map.html')というHTMLファイルとして保存すると、巨大な22MBのHTMLファイルが作成されます。

答えて

0

さまざまなユースケースがあり、その中にはやりがいのあるものがあります。他のユースケースを非常にシンプルで便利にするために、Bokehは暗黙の「現在のドキュメント」を持ち、そこに蓄積しているものを保持します。ループ内で一連のプロットを連続して生成する特定の使用例については、この蓄積を防ぐために、それぞれの間にbokeh.io.reset_output()を呼び出すことが望ましいでしょう。

+0

アドバイスありがとう - しかし、これは完全に問題を解決していません。 Bokeh側では、いくつかのテストに基づいて、グラフ自体を作成することは、あまりにも多くのメモリを使用していないようです(私はこのループで18を作っています)。しかし、 'file_html()'の呼び出しは 'bokeh.io.curdoc()。clear()'によってクリアされないメモリ使用量を追加しているようです。基本的なHTMLをBokehチャートから取得するより良い方法はありますか?いずれにしても、私の質問を編集するつもりです。なぜなら、この問題はBokehではなく、むしろフォリアムによって推進されているように思われるからです。 –

+0

'bokeh.io.reset_output()'もあります。実際にはこの種のシナリオではおそらくもっと包括的です。私は答えを更新しました。 – bigreddot

関連する問題