4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Plotly.jsで3dグラフを回転させる

Last updated at Posted at 2020-09-01

3Dグラフがその場で回転するのってかっこいいですよね。

ということで回るようにしました。
グラフにマウスを合わせて、右上にあるベルマークをクリックしてみてください。

See the Pen oNxeMZd by ririli (@ririli) on CodePen.

かっこいいね。

では軽く解説しましょう。

グラフ描画ライブラリであるPlotly.jsをcdnから取得します。

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

描画するデータ群を定義。
3Dグラフにするのでtypeはscatter3dで。


        var trace1 = {
        x: [1, 2, 3, 4],
        y: [10, 15, 13, 17],
        z: [10, 8, 6, 4],
        mode: "markers",
        type: 'scatter3d',
            marker: {
                size: markerSize,
            },
        };

        var trace2 = {
        x: [1, 2, 3, 4],
        y: [16, 5, 11, 9],
        z: [10, 8, 6, 4],
        mode:"markers",
        type: 'scatter3d',
            marker: {
                size: markerSize,
            }
        };

本題です。


       var config = {
            modeBarButtonsToAdd: [
                {
                    name: 'rotate',
                    icon: icon1,
                    click: function(gd) {
                        setInterval( () => {

                            const newData = gd._fullLayout.scene._scene.getCamera()

                            const currentX = newData.eye.x
                            const currentY = newData.eye.y
                            const currentZ = newData.eye.z

                            const newX = (currentX * Math.cos(1*(Math.PI/180))) - (currentY * Math.sin(1*(Math.PI/180)))
                            const newY = (currentX * Math.sin(1*(Math.PI/180))) + (currentY * Math.cos(1*(Math.PI/180)))

                            const update = {
                                x: newX,
                                y: newY,
                                z: currentZ
                            }

                            Plotly.relayout(gd, 'scene.camera.eye', update)
                        }, 10)
                    }
                },
            ]
        }

modeBarButtonsToAddはライブラリで定義されているもので、ここに追加したものがグラフにマウスを当てた時に出てくるメニューに追加されます。
なので、回転を開始するボタンを追加した形です。

具体的に回転される方法についてですが、

gd._fullLayout.scene._scene.getCamera()

が現在のcameraの位置を取得しています。
cameraはxyzの座標をもっていて、この座標をsetIntervalで少しずつずらすしていくことでグラフが回転しているように見せます。
実際に回転しているのはグラフではなく観測者側ってことですね。

で、横回転させるのでZ軸方向への変化は必要ありません。
XとYだけ更新します。

値の計算には三角関数を利用。
グラフを原点において円を描くようにxとyを更新します。

具体的な式がこれ。

X = xcosθ − ysinθ
Y = xsinθ + ycosθ

現在のxとyから角度θ分移動した時のXとYを求めます。
求めたXとYが次の時点のxとyになり、これを繰り返すことで円を描きます。

プログラム的には以下が該当します。

const newX = (currentX * Math.cos(1*(Math.PI/180))) - (currentY * Math.sin(1*(Math.PI/180)))
const newY = (currentX * Math.sin(1*(Math.PI/180))) + (currentY * Math.cos(1*(Math.PI/180)))

1と入れている部分がθなので、1度ずつ更新している形です。

setIntervalと組み合わせてみると、「10msecごとに1度回転」する仕組みの出来上がりです。

4
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?