【3日目】Plotlyで始める「魅せるデータ分析」～3Dグラフの作り方～

# 初めに

皆さんこんにちは！
本日はPlotlyでぐりぐり動かせちゃう3Dグラフの方、作っていきたいと思います。
- 完成イメージ
![Videotogif.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3067701/0b8ae73f-e782-b7b8-b861-f063230cf126.gif)

また、まだplotlyがよくわかってないよーって方は下記リンクから基本を学んだ後、本記事を閲覧することをおすすめします。
[【1日目】Plotlyで始める「魅せるデータ分析」～超基本編～](https://qiita.com/yamazaki_yuto/items/016cd3eb200c911f4365)

## 1点のみの表示
まずは1点だけ表示される、超シンプルな3D図を作ってみましょう。
ポイントはx, y, zの値を**リストで渡す必要がある**ということです。
※ 多少冗長な書き方をしていますが、dataをしっかり定義した方が分かりやすくなります。
```basic3d_01.py
import plotly.graph_objects as go

data_dictionaly = {
    "x": 3,
    "y": 4,
    "z": 10,
}
x = data_dictionaly["x"]
y = data_dictionaly["y"]
z = data_dictionaly["z"]

data = go.Scatter3d(
    x=[x],  # 　リストで渡すこと！
    y=[y],
    z=[z],
)

fig = go.Figure(data=data)
fig.show()
```
実行すると下記のように、1点だけ〇表示されるグラフが作成されたと思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3067701/e689a56d-e211-6cd0-1401-3dafba2e768f.png)

ここから少しずつ、応用していきましょう！


## 3点表示
表示する点を増やしたい場合は、単純にx, y, zのリストの数を増やせばよいです。下記コードではより実務的な辞書に入ったデータからリストを生成し、plotlyで表示してみましょう。

```basic3d_02.py
import plotly.graph_objects as go

data_dictionaly = {
    0: {"x": 1, "y": 2, "z": 8},
    1: {"x": 3, "y": 4, "z": 10},
    2: {"x": 5, "y": 6, "z": 12},
}
x = [data_dictionaly[i]["x"] for i in data_dictionaly]
y = [data_dictionaly[i]["y"] for i in data_dictionaly]
z = [data_dictionaly[i]["z"] for i in data_dictionaly]

data = go.Scatter3d(
    x=x,
    y=y,
    z=z,
)

fig = go.Figure(data=data)
fig.show()
```
今度は3点表示されました。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3067701/51bb412b-610a-adfd-d449-300ed53fda31.png)
## 線を非表示に
線を非表示にしたい場合、
`
mode="markers",  # デフォルトは"markers+lines"
`
とすることで線を表示することができます。


```basic3d_03.py
import plotly.graph_objects as go

data_dictionaly = {
    0: {"x": 3, "y": 1, "z": 1},
    1: {"x": 1, "y": 3, "z": 1},
    2: {"x": 1, "y": 1, "z": 3},
}
x = [data_dictionaly[i]["x"] for i in data_dictionaly]
y = [data_dictionaly[i]["y"] for i in data_dictionaly]
z = [data_dictionaly[i]["z"] for i in data_dictionaly]

data = go.Scatter3d(
    x=x,
    y=y,
    z=z,
    mode="markers",  # デフォルトは"markers+lines"
)
layout = go.Layout(
    scene=dict(
        xaxis=dict(range=[0, 5]),
        yaxis=dict(range=[0, 5]),
        zaxis=dict(range=[0, 5]),
    )
)

fig = go.Figure(data=data, layout=layout)
fig.show()
```

# 4次元データの表示
続いて、サイズを用いて表示できるデータを1種類増やしましょう。
ポイントはgo.Scatter3d()に`marker=dict(
        size=size,
    )`を渡すことです。もちろん、こちらもリストで渡す必要があります。

```basic3d_04.py
import plotly.graph_objects as go

data_dictionaly = {
    0: {"x": 3, "y": 1, "z": 1, "size": 10},
    1: {"x": 1, "y": 3, "z": 1, "size": 10},
    2: {"x": 1, "y": 1, "z": 3, "size": 50},
}
x = [data_dictionaly[i]["x"] for i in data_dictionaly]
y = [data_dictionaly[i]["y"] for i in data_dictionaly]
z = [data_dictionaly[i]["z"] for i in data_dictionaly]
size = [data_dictionaly[i]["size"] for i in data_dictionaly]
data = go.Scatter3d(
    x=x,
    y=y,
    z=z,
    mode="markers",  # デフォルトは"markers+lines"
    marker=dict(
        size=size,
    ),
)
layout = go.Layout(
    scene=dict(
        xaxis=dict(range=[0, 5]),
        yaxis=dict(range=[0, 5]),
        zaxis=dict(range=[0, 5]),
    )
)

fig = go.Figure(data=data, layout=layout)
fig.show()
```
これで4次元情報(サイズ)も表示することができました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3067701/d4ef61ba-be7f-a2a3-23c5-8450939c99dc.png)

## 複数dataの表示
最後に別のdataを一つ追加します。
ここではdata_2という名前で別のdataを追加してます。
このdataは何個でも増やすことができます。

```basic3d_05.py
import plotly.graph_objects as go

data_dictionaly = {
    0: {
        "x": 3,
        "y": 1,
        "z": 1,
        "size": 10,
    },
    1: {
        "x": 1,
        "y": 3,
        "z": 1,
        "size": 10,
    },
    2: {
        "x": 1,
        "y": 1,
        "z": 3,
        "size": 50,
    },
}
x = [data_dictionaly[i]["x"] for i in data_dictionaly]
y = [data_dictionaly[i]["y"] for i in data_dictionaly]
z = [data_dictionaly[i]["z"] for i in data_dictionaly]
size = [data_dictionaly[i]["size"] for i in data_dictionaly]

data_1 = go.Scatter3d(
    x=x,
    y=y,
    z=z,
    mode="markers",
    marker=dict(
        size=size,
    ),
    name="data_1",
)
data_2 = go.Scatter3d(
    x=[0],
    y=[0],
    z=[0],
    mode="markers",
    marker=dict(
        size=size,
    ),
    name="data_2",
)
layout = go.Layout(
    scene=dict(
        xaxis=dict(range=[0, 5]),
        yaxis=dict(range=[0, 5]),
        zaxis=dict(range=[0, 5]),
    )
)

fig = go.Figure(data=[data_1, data_2], layout=layout)
fig.show()
```
![newplot.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3067701/d30542f3-9e1a-83ab-2f96-82903a90c161.png)

# 最後に
これで簡単な5つの3Dグラフを作成できるようになりました。
あまりにも簡単なコードですが、最後のbasic3d_05.pyを書くことができれば、あとは少し応用するだけで、おおよそのグラフ作成に活かせると思っております。

是非、良いplotly lifeをお楽しみ下さい！