home about terms twitter

PythonとPlotly_Expressで気象グラフをhtml出力する

date: 2020-02-18 | mod: 2021-05-04

Pythonを介したPlotlyの使用により、グラフのHTML出力を行います。なお、今回はPlotly Expressを用います。

  • Plotly …オープンソースのデータ分析・グラフ可視化ツール(公式サイト
  • Plotly Express …より迅速にデータをグラフ化するためのパッケージ(公式サイト

PlotlyはPython以外にもRやJavascript等のパッケージも存在しますが、今回はPythonで使用してみます。


関連記事


index


コード全体

Windows 10

動作環境:

  • python 3.6.8
  • plotly 4.5.0
  • windows10 64bit

すでにplotlyはインストールされているものとします。 インストールがお済みでない場合には、公式サイト - Getting Started with Plotly in Pythonに従ってpipまたはcondaによりインストールしてください。

input output
weather_tokyo.csv plotly_graph.html
from plotly import express as px
import pandas as pd

df = pd.read_csv('weather_tokyo.csv', encoding='shift-jis', header=0)

fig = px.scatter(
    data_frame=df,
    x='月',
    y='平均気温',
    size='合計降水量',
    color='年',
    hover_name='年',
    size_max=60,
    height=400,
    width=650,
)

with open('plotly_graph.html', 'w') as f:
    f.write(fig.to_html(include_plotlyjs='cdn'))

Google Colaboratory

動作環境:

  • Linux-4.19.112+-x86_64-with-Ubuntu-18.04-bionic
  • Python 3.7.10

ドライブのマウント

from google.colab import drive
drive.mount('/gdrive')

pipを用いてplotlyのインストールを行いましたが、plotlyはすでにインストールされているようです(2021/05/04時点)。

以下のコードを実行します。

from plotly import express as px
import pandas as pd

df = pd.read_csv('/gdrive/My Drive/Colab Notebooks/weather_tokyo.csv', encoding='shift-jis', header=0)

fig = px.scatter(
    data_frame=df,
    x='月',
    y='平均気温',
    size='合計降水量',
    color='年',
    hover_name='年',
    size_max=60,
    height=400,
    width=650,
)

with open('/gdrive/My Drive/Colab Notebooks/plotly_graph.html', 'w') as f:
    f.write(fig.to_html(include_plotlyjs='cdn'))

入力ファイル、出力ファイルともにマイドライブ下のColab Notebooksフォルダに置くものとします。

ポイントを以下に示します。


ファイルの読み込み

df = pd.read_csv('weather_tokyo.csv', encoding='shift-jis', header=0)

pandasでread_csvを行い、実行するpyファイルと同じディレクトリに保存しておいた「weather_tokyo.csv」をデータフレームとして読み込みます。エンコードはshift-jisを指定します。これを指定しない場合には、

UnicodeDecodeError: 'utf-8' codec can't decode byte 0x94 in position 0: invalid start byte

というエラーが返されました(今回の実行環境の場合)。

今回は、気象庁の過去のデータから取得した2018年・2019年の月合計降水量および平均気温を用います。

年  月  合計降水量  平均気温
2018年  1  48.5  4.7
2018年  2  20  5.4
2018年  3  220  11.5
2018年  4  109  17
2018年  5  165.5  19.8
2018年  6  155.5  22.4
2018年  7  107  28.3
2018年  8  86.5  28.1
2018年  9  365  22.9
2018年  10  61.5  19.1
2018年  11  63  14
2018年  12  44  8.3
2019年  1  16  5.6
2019年  2  42  7.2
2019年  3  117.5  10.6
2019年  4  90.5  13.6
2019年  5  120.5  20
2019年  6  225  21.8
2019年  7  193  24.1
2019年  8  110  28.4
2019年  9  197  25.1
2019年  10  529.5  19.4
2019年  11  156.5  13.1
2019年  12  76.5  8.5

「年」の値は、2018, 2019と数値で指定した場合にはscatterのデフォルトの設定のためか色指定がグラデーションになってしまったため、個々のデータラベルとして扱うために「2018年」とすることで文字列として認識させています。

グラフパラメータの指定

fig = px.scatter(
    data_frame=df,
    x='月',
    y='平均気温',
    size='合計降水量',
    color='年',
    hover_name='年',
    size_max=60,
    height=400,
    width=650,
)

初めに用いるデータフレームをdata_frameで指定し、各種のグラフパラメータを指定しています。x軸に「月」、y軸に「平均気温」、散布図のプロットサイズに「合計降水量」を指定しています。サイズとして合計降水量を用いることには議論の余地があると思いますが、今回はそのままグラフを表示させます。
データを色分けする際には、colorで指定します。今回は年ごとに色分けしています。
hover_nameに「年」を指定することで、プロットにマウスカーソルを合わせる(モバイル、タブレットならタップする)ことで表示されるデータの名前が指定されます。
その他、縦横サイズの指定を行います。size_maxではプロットのサイズが変更できますが、どのような処理を行っているのかは調査が必要です。

出力

これにより得られる出力は以下の通りです。実行したファイルと同じディレクトリ内に「plotly_graph.html」が出力されています。

<html>
<head><meta charset="utf-8" /></head>
<body>
    <div>
        
                <script type="text/javascript">window.PlotlyConfig = {MathJaxConfig: 'local'};</script>
        <script src="https://cdn.plot.ly/plotly-latest.min.js"></script>    
            <div id="312d5734-6c35-4399-a7c0-bcb94407a3ab" class="plotly-graph-div" style="height:400px; width:650px;"></div>
            <script type="text/javascript">
                
                    window.PLOTLYENV=window.PLOTLYENV || {};
                    
                if (document.getElementById("312d5734-6c35-4399-a7c0-bcb94407a3ab")) {
                    Plotly.newPlot(
                        '312d5734-6c35-4399-a7c0-bcb94407a3ab',
                        [{"hoverlabel": {"namelength": 0}, "hovertemplate": "<b>%{hovertext}</b><br><br>\u5e74=2018\u5e74<br>\u6708=%{x}<br>\u5e73\u5747\u6c17\u6e29=%{y}<br>\u5408\u8a08\u964d\u6c34\u91cf=%{marker.size}", "hovertext": ["2018\u5e74", "2018\u5e74", "2018\u5e74", "2018\u5e74", "2018\u5e74", "2018\u5e74", "2018\u5e74", "2018\u5e74", "2018\u5e74", "2018\u5e74", "2018\u5e74", "2018\u5e74"], "legendgroup": "2018\u5e74", "marker": {"color": "#636efa", "size": [48.5, 20.0, 220.0, 109.0, 165.5, 155.5, 107.0, 86.5, 365.0, 61.5, 63.0, 44.0], "sizemode": "area", "sizeref": 0.14708333333333334, "symbol": "circle"}, "mode": "markers", "name": "2018\u5e74", "showlegend": true, "type": "scatter", "x": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], "xaxis": "x", "y": [4.7, 5.4, 11.5, 17.0, 19.8, 22.4, 28.3, 28.1, 22.9, 19.1, 14.0, 8.3], "yaxis": "y"}, {"hoverlabel": {"namelength": 0}, "hovertemplate": "<b>%{hovertext}</b><br><br>\u5e74=2019\u5e74<br>\u6708=%{x}<br>\u5e73\u5747\u6c17\u6e29=%{y}<br>\u5408\u8a08\u964d\u6c34\u91cf=%{marker.size}", "hovertext": ["2019\u5e74", "2019\u5e74", "2019\u5e74", "2019\u5e74", "2019\u5e74", "2019\u5e74", "2019\u5e74", "2019\u5e74", "2019\u5e74", "2019\u5e74", "2019\u5e74", "2019\u5e74"], "legendgroup": "2019\u5e74", "marker": {"color": "#EF553B", "size": [16.0, 42.0, 117.5, 90.5, 120.5, 225.0, 193.0, 110.0, 197.0, 529.5, 156.5, 76.5], "sizemode": "area", "sizeref": 0.14708333333333334, "symbol": "circle"}, "mode": "markers", "name": "2019\u5e74", "showlegend": true, "type": "scatter", "x": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], "xaxis": "x", "y": [5.6, 7.2, 10.6, 13.6, 20.0, 21.8, 24.1, 28.4, 25.1, 19.4, 13.1, 8.5], "yaxis": "y"}],
                        {"height": 400, "legend": {"itemsizing": "constant", "title": {"text": "\u5e74"}, "tracegroupgap": 0}, "margin": {"t": 60}, "template": {"data": {"bar": [{"error_x": {"color": "#2a3f5f"}, "error_y": {"color": "#2a3f5f"}, "marker": {"line": {"color": "#E5ECF6", "width": 0.5}}, "type": "bar"}], "barpolar": [{"marker": {"line": {"color": "#E5ECF6", "width": 0.5}}, "type": "barpolar"}], "carpet": [{"aaxis": {"endlinecolor": "#2a3f5f", "gridcolor": "white", "linecolor": "white", "minorgridcolor": "white", "startlinecolor": "#2a3f5f"}, "baxis": {"endlinecolor": "#2a3f5f", "gridcolor": "white", "linecolor": "white", "minorgridcolor": "white", "startlinecolor": "#2a3f5f"}, "type": "carpet"}], "choropleth": [{"colorbar": {"outlinewidth": 0, "ticks": ""}, "type": "choropleth"}], "contour": [{"colorbar": {"outlinewidth": 0, "ticks": ""}, "colorscale": [[0.0, "#0d0887"], [0.1111111111111111, "#46039f"], [0.2222222222222222, "#7201a8"], [0.3333333333333333, "#9c179e"], [0.4444444444444444, "#bd3786"], [0.5555555555555556, "#d8576b"], [0.6666666666666666, "#ed7953"], [0.7777777777777778, "#fb9f3a"], [0.8888888888888888, "#fdca26"], [1.0, "#f0f921"]], "type": "contour"}], "contourcarpet": [{"colorbar": {"outlinewidth": 0, "ticks": ""}, "type": "contourcarpet"}], "heatmap": [{"colorbar": {"outlinewidth": 0, "ticks": ""}, "colorscale": [[0.0, "#0d0887"], [0.1111111111111111, "#46039f"], [0.2222222222222222, "#7201a8"], [0.3333333333333333, "#9c179e"], [0.4444444444444444, "#bd3786"], [0.5555555555555556, "#d8576b"], [0.6666666666666666, "#ed7953"], [0.7777777777777778, "#fb9f3a"], [0.8888888888888888, "#fdca26"], [1.0, "#f0f921"]], "type": "heatmap"}], "heatmapgl": [{"colorbar": {"outlinewidth": 0, "ticks": ""}, "colorscale": [[0.0, "#0d0887"], [0.1111111111111111, "#46039f"], [0.2222222222222222, "#7201a8"], [0.3333333333333333, "#9c179e"], [0.4444444444444444, "#bd3786"], [0.5555555555555556, "#d8576b"], [0.6666666666666666, "#ed7953"], [0.7777777777777778, "#fb9f3a"], [0.8888888888888888, "#fdca26"], [1.0, "#f0f921"]], "type": "heatmapgl"}], "histogram": [{"marker": {"colorbar": {"outlinewidth": 0, "ticks": ""}}, "type": "histogram"}], "histogram2d": [{"colorbar": {"outlinewidth": 0, "ticks": ""}, "colorscale": [[0.0, "#0d0887"], [0.1111111111111111, "#46039f"], [0.2222222222222222, "#7201a8"], [0.3333333333333333, "#9c179e"], [0.4444444444444444, "#bd3786"], [0.5555555555555556, "#d8576b"], [0.6666666666666666, "#ed7953"], [0.7777777777777778, "#fb9f3a"], [0.8888888888888888, "#fdca26"], [1.0, "#f0f921"]], "type": "histogram2d"}], "histogram2dcontour": [{"colorbar": {"outlinewidth": 0, "ticks": ""}, "colorscale": [[0.0, "#0d0887"], [0.1111111111111111, "#46039f"], [0.2222222222222222, "#7201a8"], [0.3333333333333333, "#9c179e"], [0.4444444444444444, "#bd3786"], [0.5555555555555556, "#d8576b"], [0.6666666666666666, "#ed7953"], [0.7777777777777778, "#fb9f3a"], [0.8888888888888888, "#fdca26"], [1.0, "#f0f921"]], "type": "histogram2dcontour"}], "mesh3d": [{"colorbar": {"outlinewidth": 0, "ticks": ""}, "type": "mesh3d"}], "parcoords": [{"line": {"colorbar": {"outlinewidth": 0, "ticks": ""}}, "type": "parcoords"}], "pie": [{"automargin": true, "type": "pie"}], "scatter": [{"marker": {"colorbar": {"outlinewidth": 0, "ticks": ""}}, "type": "scatter"}], "scatter3d": [{"line": {"colorbar": {"outlinewidth": 0, "ticks": ""}}, "marker": {"colorbar": {"outlinewidth": 0, "ticks": ""}}, "type": "scatter3d"}], "scattercarpet": [{"marker": {"colorbar": {"outlinewidth": 0, "ticks": ""}}, "type": "scattercarpet"}], "scattergeo": [{"marker": {"colorbar": {"outlinewidth": 0, "ticks": ""}}, "type": "scattergeo"}], "scattergl": [{"marker": {"colorbar": {"outlinewidth": 0, "ticks": ""}}, "type": "scattergl"}], "scattermapbox": [{"marker": {"colorbar": {"outlinewidth": 0, "ticks": ""}}, "type": "scattermapbox"}], "scatterpolar": [{"marker": {"colorbar": {"outlinewidth": 0, "ticks": ""}}, "type": "scatterpolar"}], "scatterpolargl": [{"marker": {"colorbar": {"outlinewidth": 0, "ticks": ""}}, "type": "scatterpolargl"}], "scatterternary": [{"marker": {"colorbar": {"outlinewidth": 0, "ticks": ""}}, "type": "scatterternary"}], "surface": [{"colorbar": {"outlinewidth": 0, "ticks": ""}, "colorscale": [[0.0, "#0d0887"], [0.1111111111111111, "#46039f"], [0.2222222222222222, "#7201a8"], [0.3333333333333333, "#9c179e"], [0.4444444444444444, "#bd3786"], [0.5555555555555556, "#d8576b"], [0.6666666666666666, "#ed7953"], [0.7777777777777778, "#fb9f3a"], [0.8888888888888888, "#fdca26"], [1.0, "#f0f921"]], "type": "surface"}], "table": [{"cells": {"fill": {"color": "#EBF0F8"}, "line": {"color": "white"}}, "header": {"fill": {"color": "#C8D4E3"}, "line": {"color": "white"}}, "type": "table"}]}, "layout": {"annotationdefaults": {"arrowcolor": "#2a3f5f", "arrowhead": 0, "arrowwidth": 1}, "coloraxis": {"colorbar": {"outlinewidth": 0, "ticks": ""}}, "colorscale": {"diverging": [[0, "#8e0152"], [0.1, "#c51b7d"], [0.2, "#de77ae"], [0.3, "#f1b6da"], [0.4, "#fde0ef"], [0.5, "#f7f7f7"], [0.6, "#e6f5d0"], [0.7, "#b8e186"], [0.8, "#7fbc41"], [0.9, "#4d9221"], [1, "#276419"]], "sequential": [[0.0, "#0d0887"], [0.1111111111111111, "#46039f"], [0.2222222222222222, "#7201a8"], [0.3333333333333333, "#9c179e"], [0.4444444444444444, "#bd3786"], [0.5555555555555556, "#d8576b"], [0.6666666666666666, "#ed7953"], [0.7777777777777778, "#fb9f3a"], [0.8888888888888888, "#fdca26"], [1.0, "#f0f921"]], "sequentialminus": [[0.0, "#0d0887"], [0.1111111111111111, "#46039f"], [0.2222222222222222, "#7201a8"], [0.3333333333333333, "#9c179e"], [0.4444444444444444, "#bd3786"], [0.5555555555555556, "#d8576b"], [0.6666666666666666, "#ed7953"], [0.7777777777777778, "#fb9f3a"], [0.8888888888888888, "#fdca26"], [1.0, "#f0f921"]]}, "colorway": ["#636efa", "#EF553B", "#00cc96", "#ab63fa", "#FFA15A", "#19d3f3", "#FF6692", "#B6E880", "#FF97FF", "#FECB52"], "font": {"color": "#2a3f5f"}, "geo": {"bgcolor": "white", "lakecolor": "white", "landcolor": "#E5ECF6", "showlakes": true, "showland": true, "subunitcolor": "white"}, "hoverlabel": {"align": "left"}, "hovermode": "closest", "mapbox": {"style": "light"}, "paper_bgcolor": "white", "plot_bgcolor": "#E5ECF6", "polar": {"angularaxis": {"gridcolor": "white", "linecolor": "white", "ticks": ""}, "bgcolor": "#E5ECF6", "radialaxis": {"gridcolor": "white", "linecolor": "white", "ticks": ""}}, "scene": {"xaxis": {"backgroundcolor": "#E5ECF6", "gridcolor": "white", "gridwidth": 2, "linecolor": "white", "showbackground": true, "ticks": "", "zerolinecolor": "white"}, "yaxis": {"backgroundcolor": "#E5ECF6", "gridcolor": "white", "gridwidth": 2, "linecolor": "white", "showbackground": true, "ticks": "", "zerolinecolor": "white"}, "zaxis": {"backgroundcolor": "#E5ECF6", "gridcolor": "white", "gridwidth": 2, "linecolor": "white", "showbackground": true, "ticks": "", "zerolinecolor": "white"}}, "shapedefaults": {"line": {"color": "#2a3f5f"}}, "ternary": {"aaxis": {"gridcolor": "white", "linecolor": "white", "ticks": ""}, "baxis": {"gridcolor": "white", "linecolor": "white", "ticks": ""}, "bgcolor": "#E5ECF6", "caxis": {"gridcolor": "white", "linecolor": "white", "ticks": ""}}, "title": {"x": 0.05}, "xaxis": {"automargin": true, "gridcolor": "white", "linecolor": "white", "ticks": "", "title": {"standoff": 15}, "zerolinecolor": "white", "zerolinewidth": 2}, "yaxis": {"automargin": true, "gridcolor": "white", "linecolor": "white", "ticks": "", "title": {"standoff": 15}, "zerolinecolor": "white", "zerolinewidth": 2}}}, "width": 650, "xaxis": {"anchor": "y", "domain": [0.0, 1.0], "title": {"text": "\u6708"}}, "yaxis": {"anchor": "x", "domain": [0.0, 1.0], "title": {"text": "\u5e73\u5747\u6c17\u6e29"}}},
                        {"responsive": true}
                    )
                };
                
            </script>
        </div>
</body>
</html>

出力されたhtmlを実際にウェブページに貼り付けると、以下のようなグラフが出力されます。
なお、今回は

タグで囲まれた部分のみ貼り付け、タグは省略しました。

(241010追記: グラフの表示を省略しました)

目的のグラフが出力されたことを確認できました。
また、Plotlyの特徴でもあるインタラクティブなグラフの操作が可能なことが確認できます。
視点が変更可能ですが、もとの表示に戻したいときにはページを更新するか、家🏠のマーク(Reset axes)を選択してください。その他、上部のボタンで各種の操作が可能です。
データの内容そのものについては、2019年の7月は前年より気温が低下したこと、2019年の10月には前年より多く雨が降ったこと等が見て取れました。

関連記事