plotly散布図で使いそうなtrace, layoutのテンプレート

# はじめに
plotlyで散布図を描く際に使いそうなtrace, layoutのテンプレートです
必要ない個所は適宜消してください

# 環境
Mac OS
python 3.8.5
plotly 4.12.0

# pip

```terminal
pip install plotly
```

# traceテンプレート

```python
import plotly.offline as offline
import plotly.graph_objs as go

import plotly
colors = plotly.colors.DEFAULT_PLOTLY_COLORS
"""
デフォルトカラー取得
['rgb(31, 119, 180)', 'rgb(255, 127, 14)', 'rgb(44, 160, 44)', 'rgb(214, 39, 40)', 'rgb(148, 103, 189)',
 'rgb(140, 86, 75)', 'rgb(227, 119, 194)', 'rgb(127, 127, 127)', 'rgb(188, 189, 34)', 'rgb(23, 190, 207)']
"""

from plotly.validators.scatter.marker import SymbolValidator
raw_symbols = SymbolValidator().values
"""
マーカーシンボルに使える値
[0, '0', 'circle', 100, '100', 'circle-open',...
474個ある
https://plotly.com/python/marker-style/#custom-marker-symbols
"""
data = []
trace = go.Scatter(
    x=[i for i in range(10)],
    y=[i for i in range(10)],
    yaxis="y1",  # yの第?軸 "y2", "y3", "y4", ..　https://plotly.com/python/multiple-axes/#multiple-axes
    line=dict(color=colors[0], width=6, dash="dashdot"),
    # dash="dash", "dot" or "dashdot" https://plotly.com/python/line-charts/#style-line-plots

    line_shape="hv",
    # ステップなど "hv", "vh", "hvh", "vhv", "spline", "liner" https://plotly.com/python/legend/#hiding-the-trace-initially

    marker=dict(color=colors[0], size=10, line=dict(color="red", width=2)),
    # line=マーカーの輪郭線情報　https://plotly.com/python/marker-style/#add-marker-border

    mode="lines+markers",
    # "lines", "lines+markers" or "markers" https://plotly.com/python/line-charts/#line-plot-modes

    marker_symbol=raw_symbols[0],  # マーカーの形を指定 https://plotly.com/python/marker-style/#custom-marker-symbols
    name="sample",  # 凡例に使われる
    hovertemplate="y: %{y}<br>x: %{x}",
    opacity=1,  # 透明度 0~1 https://plotly.com/python/marker-style/#color-opacity
    visible=True,  # True, False or legendonly
    showlegend=True,  # 凡例表示 True or False
    legendgroup="sample"  # 文字列が同じtraceは表示/非表示切り替えが同期する https://plotly.com/python/legend/#grouped-legend-items
)
data.append(trace)

```
# layoutテンプレート
## 基本
title, xaxisなどとりあえずこれがあればグラフの体裁ができるlayout

```python
layout = go.Layout(
    title=dict(text='<b>sample title</b><br>text', font=dict(size=16)),
    xaxis=dict(title=dict(text='x axis label', font=dict(size=12)), tickfont=dict(size=12), autorange=True),
    # https://plotly.com/python/reference/layout/xaxis/
    
    yaxis=dict(title='y axis label'),
    font=dict(size=16),  # グローバルフォント
    newshape=dict(line=dict(color="cyan", width=4, dash="solid")),
    # dash='solid', 'dot', 'dash', 'longdash', 'dashdot','longdashdot'
    autosize=True,
    showlegend=True, )

fig = dict(data=data, layout=layout)

offline.plot(fig, include_plotlyjs="cdn", auto_open=True, filename='sample plotly.html', config={
    'modeBarButtonsToAdd': ['drawline', 'drawopenpath', 'drawclosedpath', 'drawcircle', 'drawrect', 'eraseshape']}, )
```
`title=dict(text='<b>sample title</b><br>text'`
文字列個所にはhtmlのタグが使える, `<b>str</b>`で太字、`<br>`で改行
太字で色付きにしたければ`<b style="color:red">test</b>`など

最後の行で右上に線や円を描けるボタンを追加
`config={'modeBarButtonsToAdd': ['drawline', 'drawopenpath', 'drawclosedpath', 'drawcircle', 'drawrect', 'eraseshape']}`



### 第２軸
traceで`yaxis="y2"`にしておく

`yaxis2=`の個所

```python
layout = go.Layout(
    title=dict(text='<b>sample title</b><br>text', font=dict(size=16)),
    xaxis=dict(title=dict(text='x axis label', font=dict(size=12)), tickfont=dict(size=12), tickangle=0),
    # https://plotly.com/python/reference/layout/xaxis/

    yaxis=dict(title="y axis label"),  # xaxisと同上
    yaxis2=dict(title="y2 axis label", overlaying="y", side="right", showgrid=False),
    font=dict(size=16),  # グローバルフォント
    newshape=dict(line=dict(color="cyan", width=4, dash="solod")),
    # dash='solid', 'dot', 'dash', 'longdash', 'dashdot','longdashdot'
    autosize=True,
    showlegend=True, )

fig = dict(data=data, layout=layout)

offline.plot(fig, include_plotlyjs="cdn", auto_open=True, filename='sample plotly.html', config={
    'modeBarButtonsToAdd': ['drawline', 'drawopenpath', 'drawclosedpath', 'drawcircle', 'drawrect', 'eraseshape']}, )
```

### その他使うもの
title, xaxisのフォント形式も変えたい時、xaxisの範囲を決めたい時、ホバーやスパイクなどその他変更するとき

```python
layout = go.Layout(
    title=dict(text='<b>sample title</b><br>text', font=dict(family="Arial", size=16, color="black")),
    xaxis=dict(title=dict(text='x axis label', font=dict(family="Arial", size=12, color="black")),
               tickfont=dict(family="Arial", size=12, color="black"), type="-", tick0=0, dtick=1, range=[0, 100],
               autorange=True, rangemode="normal", tickangle=0, tickformat="", color="white", showspikes=True,
               spikemode="toaxis", spikecolor="red", domain=[0, 1]),  # https://plotly.com/python/reference/layout/xaxis/

    yaxis=dict(title='y axis label', spikemode="toaxis", domain=[0, 1]),  # xaxisと同上
    font=dict(family="Arial", size=16, color="black"),  # グローバルフォント
    legend=dict(orientation="h", yanchor="bottom", y=1.02, xanchor="right", x=1),  # orientation=h 凡例を横表示にする
    newshape=dict(line=dict(color="cyan", width=4, dash="dashdot")),
    # dash='solid', 'dot', 'dash', 'longdash', 'dashdot','longdashdot'

    hovermode='x unified',  # "x", "y", "closest", False, "x unified", "y unified"
    hoverlabel=dict(font=dict(family="Arial", size=20, color="black"), bgcolor="white", bordercolor="black"),
    # paper_bgcolor="#ffffff",  # プロット外の色指定
    # plot_bgcolor="#ffffff",  # プロット内の色指定
    # template="plotly_dark",  # テンプレート https://plotly.com/python/templates/
    autosize=True,
    showlegend=True, )

fig = dict(data=data, layout=layout)

offline.plot(fig, include_plotlyjs="cdn", auto_open=True, filename='sample plotly.html', config={
    'modeBarButtonsToAdd': ['drawline', 'drawopenpath', 'drawclosedpath', 'drawcircle', 'drawrect', 'eraseshape']}, )
```
#### xaxis yaxis
`font=dict(family="Arial", size=16, color="black")`でフォントの形式、サイズ、色を指定
> family="Arial", "Balto", "Courier New", "Droid Sans",, "Droid Serif", "Droid Sans Mono", "Gravitas One", "Old Standard TT", "Open Sans", "Overpass", "PT Sans Narrow", "Raleway", "Times New Roman".

`tickfont=dict(family="Arial", size=12, color="black")`で軸の値のフォントを指定
`type="-"`： 入力値によって時間軸やログスケールなどに変更
>  "-" | "linear" | "log" | "date" | "category" | "multicategory"
Default: "-"

`tick0`： 軸の最小値を指定
`dtick`： 軸の目盛間隔指定
`range=[min, max]`： 表示する軸の最大・最小を指定
`autorange=True`: 与えられた値によって自動で範囲を設定する, rangeが入力されるとFalseになる
> ( True | False | "reversed" )

`rangemode`: normal:入力値によって軸範囲を決める、tozero:０が原点、nonnefative:非負
> Type: enumerated , one of ( "normal" | "tozero" | "nonnegative" )
Default: "normal"

`tickangle`: 軸値の表示角度、デフォルトは"auto"
`tickformat`: %表示などにしたい時、デフォルトは`""`
`color`: axisの色指定（label, tickの両方）
`showspikes`:スパイク（プロットにカーソルを近づけた時に出る点線）の表示/非表示 
`spikemode`: スパイクの表示方法の変更
> Type: flaglist string. Any combination of "toaxis", "across", "marker" joined with a "+"
Examples: "toaxis", "across", "toaxis+across", "toaxis+across+marker"
Default: "toaxis"

`spikecolor`: スパイクの色
`domain`: グラフ領域の指定、デフォルトは[0, 1], 範囲は0~1

#### legend
`orientation="h", yanchor="bottom", y=1.02, xanchor="right", x=1`
凡例を横向きにする。
右下をグラフ座標のy=1.02, x=1に合わせる。
座標はグラフ（axisより内側の青色の部分）の左下が(x, y)=(0, 0), 右上が(x, y)=(1, 1)

#### hovermode
プロットにカーソルを近づけた時の値の表示方法変更
> "x", "y", "closest", False, "x unified", "y unified"

#### その他
`paper_bgcolor`: プロット外の色指定
`plot_bgcolor`: プロット内の色指定
`template`: グラフのテンプレート、`"plotly_dark"`がかっこいい
https://plotly.com/python/templates/


## 時間軸
x軸の値はdatetimeなど時刻にしておく必要有

```python
layout = go.Layout(
    title="sample",
    xaxis=dict(title="time", type="date", rangeslider=dict(visible=True), tickformat="%Y/%m/%d %H:%M:%S",
               dtick=86400000.0 / 24),
    yaxis=dict(title='y axis label'),
    font=dict(size=16),
    newshape=dict(line=dict(color="cyan", width=4, dash="solid")),
    hovermode='x unified',
    hoverlabel=dict(font=dict(size=20)),
    autosize=True,
    showlegend=True)

fig = dict(data=data, layout=layout)

offline.plot(fig, include_plotlyjs="cdn", auto_open=True, filename='sample plotly2.html', config={
    'modeBarButtonsToAdd': ['drawline', 'drawopenpath', 'drawclosedpath', 'drawcircle', 'drawrect', 'eraseshape']}, )

```
`type="date"`: 時間軸に変更
`rangeslider=dict(visible=True)`: グラフの下にグラフの表示範囲をいじれるスライダーを追加
`tickformat`:時刻表示形式を指定
> "%Y/%m/%d %H:%M:%S" = yyyy/mm/dd HH:MM:SS
%yは西暦の下２桁

`dtick`: 軸間隔を指定
> "M1"で１ヶ月ごと -> "M2"で２ヶ月ごと
"D1"で一日ごと -> "D2"で二日ごと
その他は`86400000.0`ごとに一日追加（一日の秒数60*60*24=86400000）

## スライダー
別記事に詳細
[plotly スライダーを使ったグラフの応用 - Qiita](https://qiita.com/shu32/items/f9ba57babb072363b466)


# 参考サイト
公式
[Plotly Python Graphing Library | Python | Plotly](https://plotly.com/python/)

時間軸参考
[Plotly 日付軸ラベルの表示設定 : showeryのブログ](http://hxn.blog.jp/archives/9505573.html)