【plotlyの描画構造の話】plotlyで動的な可視化をする【python】


plotlyの構造について理解する話

#plotlyとは


plotlyはJavaScript,R,Pythonで利用可能な動的グラフを作るパッケージです

動的グラフというのは以下の様に動かすことができるグラフのこと

![aaa.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/cbb55ca0-6738-83a9-f62d-449a6a68810d.gif)


他の関数と同じく指定された引数を用意することで動的グラフが簡単につくることができます
他のplotlyと区別するためJavascript「plotly.js」pythonは「plotly.py」と呼ばれたりもします

#plotlyの中身と動き

plotlyはpandasのようなデータフレーム、もしくはnumpyのarrayを一度json形式に変形して保持し、
javascriptによってhtmlとして実行・保存できるようになっています

テキストエディターで以下のようなhtmlを作成するとplotlyのbarplotが作成されます



```html

<body>
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>

<div id="graph" style="width: 600px; height: 400px;"></div>

<script>
  // Xの値を書く
  var x = ["giraffes","orangutans","monkeys"];
  // Yの値を書く
  var y = [20,14,23];
  var data = [{ name: 'sample', x : x, y : y, type: 'bar'}];
  var layout = { legend : { showlegend : false } };
  Plotly.newPlot("graph", data, layout);
</script>

</body>

```



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/d927c2ea-4d1b-9de2-240a-5ec73512df20.png)


#pythonの場合は?

python==3.8
plotly==4.10.0


同じことをpythonで行ってみます

```python
import plotly.express as px
fig = px.bar(x=["giraffes","orangutans","monkeys"], 
            y=[20,14,23])
fig.show()
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/d13e8f7f-2469-4c19-92ee-0b4c8373b94e.png)


htmlで行うよりもpythonで行うほうがデータフレームや行列が扱いやすく、受け渡しもスムーズにできます。
何より関数として完成されていて極力少ないコードでの実行ができます


先ほど内部データをjson型で保有していると記述しました
plotlyにはoffline plot機能があり、pythonで作ったjson形式のデータをここに直接ぶち込むことで
関数で行っていること同じように実行できます



```python

data2=[dict(x=["giraffes","orangutans","monkeys"], 
            y=[20,14,23],
            type='bar'
           )]

import plotly

plotly.offline.iplot({
    "data": data2
})
```

data2は

```
[{'x': ['giraffes', 'orangutans', 'monkeys'],
  'y': [20, 14, 23],
  'type': 'bar'}]
```

として保持されます。
必ずdictやlistで作成する必要は無く、
同じような構造のデータに整形することができれば問題ありません


```python
data2=[
{
  "x": [
    "giraffes",
    "orangutans",
    "monkeys"
    ],
  "y": [
    20,
    14,
    23
    ],
  "type": "bar"
}
    ]
```


やってみます


```python
import plotly

plotly.offline.iplot({
    "data": data2
})
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/1ca2ef36-aef3-698a-7e59-9d8d5fa0c2fd.png)



できました。

このように「data」と、上記では出ていませんが「layout」をjsonとして与えてあげることでplotを完成させてくれます。

公式web referenceのbar関数で説明されている引数を渡すことでplotできるのですが、
json型での渡し方を覚えておくとtitle等を自由に変更できるようになります

(こだわり出すと労力も爆上がりするのでそこは様子を見ながら)


公式の関数説明でも似たようなjson形式での説明がされている場合があり、
このような構造を理解しておくと学びやすいかと思います



#せっかくなのでlayoutの話も


scatter_geoを使い、layoutも指定してみます


```python
import plotly
import pandas as pd
import plotly.express as px

geo_info = pd.DataFrame()

geo_info['latitude']=[36,50]
geo_info['longitude']=[140,50]
geo_info['color']=[80,5]

fig = px.scatter_geo(geo_info,
                     lat='latitude',
                     lon='longitude',
                     color='color',
                     range_color=(0, 100),
                     title='Tokyo and Paris',
                     projection="equirectangular")
fig.show()
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/de03484a-73d2-8341-7f70-fe82e089e1d3.png)




とても楽に立派なplotをすることができました

layoutを使って表示タイトルの変更や、dataからカラーバーの名前を変更してみます
カラーバーの名前はデフォルトでは渡された列名を付ける規則になっています

```python
data1 = [dict(type='scattergeo',
              lat=geo_info['latitude'],
              lon=geo_info['longitude'],
              
              marker = dict(#size = 9, 
                            #autocolorscale=False,
                            #colorscale = 'Viridis',
                            color = geo_info['color'], 
                            colorbar = dict(title='color bar!!!')
                           )
             )]

layout1 = dict(title='Tokyo and Paris from layout',
               geo = dict(projection = dict(type ='equirectangular'),
                          showland = True,
                          #landcolor="rgb(250,250,250)",
                          #subunitcolor = "rgb(217,217,217)",
                          #countrycolor = "rgb(217,217,217)",
                          countrywidth =0.5, 
                          subunitwidth=0.5)
              )


import plotly

plotly.offline.iplot({
    "data": data1,
    "layout": layout1
})
```


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/fbfe7e01-e9e0-a48b-c798-d68260d22306.png)



できました。

このように自在にカスタムできるようになります
頭の片隅に置いておいていただけると、plotlyを使っていく上で理解の助けになるかと思います


#json形式を確認したい

カスタムしたいけどjsonをどう渡したらいいのかわからない場合は
[plotly chart-studio](https://chart-studio.plotly.com/feed/#/)から描画したいplot typeを選択してviwerから


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/423b0b06-e11c-35c4-3c7d-af6471da88ab.png)

python&Rを選択して


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/275572/bd45127d-cab5-0166-0450-058024d0eee8.png)

どのようにデータを渡しているのか、jsonを確認することができます
これをoffline plotに渡すことで描画できます




#以上