简体   繁体   中英

Plotly: How to put two 3D graphs on the same plot with plotly.graph_objects?

In below code, I draw 2 3D graphs with plotly.graph_objects . I'm unable to put them together.

import plotly.graph_objects as go
import numpy as np

pts = np.loadtxt(np.DataSource().open('https://raw.githubusercontent.com/plotly/datasets/master/mesh_dataset.txt'))
x, y, z = pts.T

### First graph
fig = go.Figure(data=[go.Mesh3d(x=x, y=y, z=z,
                   alphahull=5,
                   opacity=0.4,
                   color='cyan')])
fig.show()
#######

x = [0, 1, 0]
y = [0, 2, 3]
tvects = [x,y]
orig = [0,0,0]
df=[]
coords = [[orig, np.sum([orig, v],axis=0)] for v in tvects]

for i,c in enumerate(coords):
    X1, Y1, Z1 = zip(c[0])
    X2, Y2, Z2 = zip(c[1])
    vector = go.Scatter3d(x = [X1[0],X2[0]],
                          y = [Y1[0],Y2[0]],
                          z = [Z1[0],Z2[0]],
                          marker = dict(size = [0,5],
                                        color = ['blue'],
                                        line=dict(width=5,
                                                  color='DarkSlateGrey')),
                          name = 'Vector'+str(i+1))
    data.append(vector)

### Second graph
fig = go.Figure(data=data)
fig.show()
########

Could you please elaborate on how to do so, and how to have the arrow with head rather than a line in the second graph?

If you'd like to build on your first fig definition, just include the following after your first call to go.Figure()

data = fig._data

data is now a list which will have new elements appended to it in the rest of your already exising code under:

for i,c in enumerate(coords):
    X1, Y1, Z1 = zip(c[0])
    X2, Y2, Z2 = zip(c[1])
    vector = go.Scatter3d(<see details in snippet below>)
    data.append(vector)

Result:

在此处输入图像描述

Regarding the arrows, the only options dierectly available to you through go.Scatter3D are:

['circle', 'circle-open', 'square', 'square-open','diamond', 'diamond-open', 'cross', 'x']

I hope one of those options will suit your needs. You can specify which one in:

marker = dict(size = [15,15],
            color = ['blue'],
            symbol = 'diamond',
            line=dict(width=500,
                      #color='red'
                     )),

Complete code:

import plotly.graph_objects as go
import numpy as np

pts = np.loadtxt(np.DataSource().open('https://raw.githubusercontent.com/plotly/datasets/master/mesh_dataset.txt'))
x, y, z = pts.T

### First graph
fig = go.Figure(data=[go.Mesh3d(x=x, y=y, z=z,
                   alphahull=5,
                   opacity=0.4,
                   color='cyan')])
#fig.show()
#######

data = fig._data

x = [0, 1, 0]
y = [0, 2, 3]
tvects = [x,y]
orig = [0,0,0]
df=[]
coords = [[orig, np.sum([orig, v],axis=0)] for v in tvects]

# ['circle', 'circle-open', 'square', 'square-open','diamond', 'diamond-open', 'cross', 'x']

for i,c in enumerate(coords):
    X1, Y1, Z1 = zip(c[0])
    X2, Y2, Z2 = zip(c[1])
    vector = go.Scatter3d(x = [X1[0],X2[0]],
                          y = [Y1[0],Y2[0]],
                          z = [Z1[0],Z2[0]],
                          marker = dict(size = [15,15],
                                        color = ['blue'],
                                        symbol = 'diamond',
                                        line=dict(width=500,
                                                  #color='red'
                                                 )),
                          name = 'Vector'+str(i+1))
    data.append(vector)

### Second graph
fig = go.Figure(data=data)
fig.show()
########

It seems that the data argument in go.Figure() accepts a list of plot objects as input. Try something like the code below:

    fig = go.Figure(data=[
        go.Scatter3d(
            x=data['tilt'].to_numpy(), y=data['pan'].to_numpy(), z=data['z'].to_numpy(),
            mode='markers',
            marker=dict(size=5, color='red', opacity=1)
        ),
        go.Scatter3d(
            x=samples[:, 0], y=samples[:, 1], z=samples[:, 2], mode='markers',
            marker=dict(size=5, color='blue', opacity=1)
        )
    ])

and you will get something like in the image: result

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM