I’m quite new to Plotly. I’m trying to generate a plot that combines a 3D surface plot (from a volume) with 2D planar surfaces.
For the first bit, I followed this guide, using create_trisurf
to visualise a 3D “segment”, i.e. a number of 2D segmentations (binary masks) that define a 3D volume.
from skimage import measure
from plotly import figure_factory as FF
from plotly.offline import iplot
init_notebook_mode(connected=True)
image = PixArr.transpose(2,1,0)
verts, faces = measure.marching_cubes_classic(image, spacing=image.shape)
x,y,z = zip(*verts)
colormap=['rgb(255,105,180)','rgb(255,255,51)','rgb(0,191,255)']
fig = FF.create_trisurf(x=x,
y=y,
z=z,
plot_edges=False,
colormap=colormap,
simplices=faces,
backgroundcolor='rgb(64, 64, 64)',
title='Segment')
iplot(fig)
PixArr
is a numpy array of shape (F, C, R), containing F frames of 2D binary masks with R rows and C columns.
I managed to get what I wanted from the segmentation data.
Next I followed the example here to plot a plane.
I wrote a function that takes a list of DICOM images and generates a list of points that mark out the corners of each image, and I unpack the points into lists X
, Y
and Z
of the x, y and z-coordinates for one of the “boxes” that defines one plane and plot it:
data = [{'type': 'mesh3d',
'x': X,
'y': Y,
'z': Z,
'color': 'red',
'opacity': 0.1}]
plane = go.Figure(data=data, layout={})
iplot(plane)
That also worked, but I was unable to loop through each set of X
, Y
, Z
lists for each plane using add_trace
to plot all planes in the figure. It appears that add_trace
cannot be used for go.Figure()
. That’s one issue, but the solution to that may lie in the next barrier I hit: Trying to combine a planar trace to the trisurf graph.
I tried to follow the solution posted for this thread, i.e.
Data = [fig.data[0], fig.data[1], plane]
iplot(Data)
but I got the following traceback:
ValueError:
Invalid element(s) received for the ‘data’ property of
Invalid elements include: [Figure({
‘data’: [{‘color’: ‘red’,
‘opacity’: 0.1,
‘type’: ‘mesh3d’,
‘x’: [-129.80790963, 126.19209036999999, 126.19209042250645,
-129.80790957749355],
‘y’: [-109.97568891, -109.97568896250647, 146.02431103749353,
146.02431109],
‘z’: [73.859869, 73.859869, 73.859869, 73.859869]}],
‘layout’: {‘template’: ‘…’}
})]The 'data' property is a tuple of trace instances that may be specified as: - A list or tuple of trace instances (e.g. [Scatter(...), Bar(...)]) - A single trace instance (e.g. Scatter(...), Bar(...), etc.) - A list or tuple of dicts of string/value properties where: - The 'type' property specifies the trace type One of: ['area', 'bar', 'barpolar', 'box', 'candlestick', 'carpet', 'choropleth', 'choroplethmapbox', 'cone', 'contour', 'contourcarpet', 'densitymapbox', 'funnel', 'funnelarea', 'heatmap', 'heatmapgl', 'histogram', 'histogram2d', 'histogram2dcontour', 'image', 'indicator', 'isosurface', 'mesh3d', 'ohlc', 'parcats', 'parcoords', 'pie', 'pointcloud', 'sankey', 'scatter', 'scatter3d', 'scattercarpet', 'scattergeo', 'scattergl', 'scattermapbox', 'scatterpolar', 'scatterpolargl', 'scatterternary', 'splom', 'streamtube', 'sunburst', 'surface', 'table', 'treemap', 'violin', 'volume', 'waterfall'] - All remaining properties are passed to the constructor of the specified trace type (e.g. [{'type': 'scatter', ...}, {'type': 'bar, ...}])
I would greatly appreciate some (newbie-level) help in understanding what went wrong, or guidance on how I can go about combining these two different graph types, ideally, with multiple planar graphs. Thanks.