#背景
データ解析などをやる人はよくjupyterを使うみたいですね。
おそらくデータを即座にグラフにして描画する、みたいなのはPython 単体では苦手なので、ブラウザ上でやってるんだと思います。
しかし、displayなどの表示(html描画)関係のメソッドは、jupyter特有のものであり、他の環境では実行できません。
Qiitaのデータ解析記事などを参考にしても、jupyterの環境の記事だと、描画周りが自分の環境だとうまくいかなかったりします。
今回は、pandas-highchartsで表示するグラフをpycharm環境から見る必要があったので記事化しました。
*2020/06/19 手違いで動かないものを公開していました。修正いたします。
#方法
pandas-highchartsのソースコードを参考に、以下のような関数を作りました。
pandas-highchartsのdisplay_chartsは、returnでdisplayにしてしまっているため、返り値はNoneになります。その一歩手前でhtmlのテンプレートに埋め込んでリターンしている感じです。
(参考)
https://github.com/gtnx/pandas-highcharts/blob/master/pandas_highcharts/display.py
def my_display_charts(df, chart_type="default", render_to=None, **kwargs):
from pandas_highcharts.core import serialize
if chart_type not in ("default", "stock"):
raise ValueError("Wrong chart_type: accept 'default' or 'stock'.")
chart_id = render_to if render_to is not None else "chart_idXXXXXXXX"
json_data = serialize(df, render_to=chart_id, chart_type=chart_type, **kwargs)
content = """
<div id="{chart_id}"</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/highcharts/8.1.1/highstock.min.js"></script>
<script type="text/javascript">{data}</script>
"""
html = """
<!DOCTYPE html>
<html lang="ja">
<head>
<title>My Result</title>
</head>
<body>
{content}
</body>
</html>
"""
return html.format(content=content.format(chart_id=chart_id, data=json_data))
使い方はこんな感じです。
import pandas as pd
import webbrowser
import os
def my_display_charts(df, chart_type="default", render_to=None, **kwargs):
from pandas_highcharts.core import serialize
from pandas_highcharts.display import _generate_div_id_chart
if chart_type not in ("default", "stock"):
raise ValueError("Wrong chart_type: accept 'default' or 'stock'.")
chart_id = render_to if render_to is not None else _generate_div_id_chart()
json_data = serialize(df, render_to=chart_id, chart_type=chart_type, **kwargs)
content = """
<div id="{chart_id}"</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/highcharts/8.1.1/highstock.min.js"></script>
<script type="text/javascript">{data}</script>
"""
html = """
<!DOCTYPE html>
<html lang="ja">
<head>
<title>My Result</title>
</head>
<body>
{content}
</body>
</html>
"""
return html.format(content=content.format(chart_id=chart_id, data=json_data))
df = pd.DataFrame([1, 2, 3, 5, 4], index=[list('abcde')])
html_data = my_display_charts(df, chart_type="stock", title="Mt Result", figsize=(640, 480), grid=True)
path = 'index.html'
with open(path, mode='w') as f:
f.write(html_data)
webbrowser.open_new_tab('file:///' + os.getcwd() + '/' + path_w)
うまくいけば、自分のPCのデフォルトのブラウザでこんな感じに描画されます。
毎回ブラウザが開くのがうざいですが、とりあえず見れます。
適当に生成したDataframeなのでグラフがダサいですね。
#考察
横軸がデフォルトでタイムスタンプなのはなんでだろうか。
webbrowserに、文字列のままhtml要素が渡せると最高なのだが、どうやらパスを渡す方法しかないようなので、今回は一度index.htmlとして書き出している。
同じ要領で、IPython.displayやpython-higchartなども、html要素さえ抜き出せれば同様にブラウザ表示できる。
今回はhighstock.min.jsだけ読み込めばいけたが、場合によってはhighchart.jsとかも必要かもしれない。
highstock.min.jsに関しては公式がどこにあるのかわからなかったので以下から持ってきている。
https://cdnjs.com/libraries/highcharts
公式ページはこちら
https://www.highcharts.com/