3D Isosurface Plots with Plotly in Python
Data visualization is one of the highlights of data analysis as it involves a graphical representation of data to help extract insights and patterns simply from raw data. We can enhance our ability to interpret data-driven findings greatly!
Utilizing Plotly's dynamic capabilities, we can now transform raw data into highly interactive plots which are seamless in rendering.
In this answer, we will cover a highly interesting type of data visualization plot, an isosurface plot, using this library.
Plotly
Plotly is a data visualization library that allows us to create rich and dynamic visualizations in Python, R, and JavaScript. We can create plots ranging from line graphs and bar charts to maps and 3D visualizations. Some interesting features of Plotly include the following:
zooming
panning
tooltips
rotating
downloading plots
Let's first understand what isosurface plots are and then implement them.
Isosurface plots
The word isosurface is a combination of iso and surface. Iso refers to "same." An isosurface plot is a type of three-dimensional visualization that represents any surface within a three-dimensional space with the condition that all points on the surface should have the same value. It is used to represent constant value points like temperature or pressure.
We can call it to be the 3D equivalent of contour line plots.
Syntax
The go.Isosurface function creates a 3D isosurface plot by connecting points with the same value within a given range, creating wonderful isosurface plots!
We have to call it within the go.Figure function to render the interactive figure on the screen.
Parameters
A few common parameters for the go.Isosurface function have been mentioned in the table below.
Parameter | Explanation |
x | y | z | Coordinates of data points in 3D space |
value | Values associated with each data point |
opacity | Opacity of the isosurface |
isomin | Minimum value for the isosurface threshold |
isomax | Maximum value for the isosurface threshold |
surface_count | Number of isosurfaces to display |
caps | Visibility of caps of the isosurface |
colorscale | Colorscale to apply to the isosurface |
Code implementation
To understand 3D isosurface plots, we will implement various such plots with different customizations and understand how they work.
Basic 3D isosurface plots
The following code is the basic foundation of isosurface plots.
import plotly.graph_objects as go
fig = go.Figure(data=go.Isosurface(
x=[0,0,0,0,2,2,2,2],
y=[3,0,3,0,3,0,3,0],
z=[2,2,5,5,2,2,5,5],
value=[1,2,3,4,5,6,7,8],
isomin=2,
isomax=6,
colorscale='magma',
))
fig.update_layout(scene=dict(
xaxis_title='X Axis',
yaxis_title='Y Axis',
zaxis_title='Z Axis'
))
fig.show()
fig.write_html("output.html", auto_open=True)Code explanation
Line 1: First, we import the necessary modules for our code. We use
plotly.graph_objectswith the alias namegofor our interactive plotting.Lines 3–11: Next up, we create a new
Figureobjectfigand add anIsosurfaceplot to it using thego.Isosurface()function. Let's go through its parameters:x,y, andz: These lists represent the coordinates of vertices in 3D.value: This list represents the scalar values of each vertex of the isosurface.isominandisomax: These parameters represent the minimum and maximum scalar values for the isosurface, respectively.colorscale: This parameter determines the color scale for our diagram. For instance, 'magma' here.
Lines 13–17: Having configured the figure, we now update the layout of the figure's scene using
fig.update_layout(). In thesceneparameter, we customize the axis titles.Line 19: Finally, we use
fig.show()to display our isosurface plot with our given data. We can see a browser open in which the interactive plot is rendered.
Note: To save the output in an HTML file,
fig.write_html("output.html", auto_open=True)can be used.
Demonstration
This is what our basic plot looks like.
Advanced 3D isosurface plots
We will now be implementing isosurface plots with greater customization. Different equations can be modeled using such plots as well.
import plotly.graph_objects as go
import numpy as np
X, Y, Z = np.mgrid[-5:5:40j, -5:5:40j, -5:5:40j]
values = (X**2 + Y**2 + Z**2) * np.exp(-0.2 * ((X - 2)**2 + (Y + 2)**2 + (Z - 2)**2))
fig = go.Figure(data=go.Isosurface(
x=X.flatten(),
y=Y.flatten(),
z=Z.flatten(),
value=values.flatten(),
isomin=1,
isomax=10,
caps=dict(x_show=False, y_show=False),
colorscale='electric',
))
fig.update_layout(
scene=dict(
xaxis_title='X Axis',
yaxis_title='Y Axis',
zaxis_title='Z Axis',
bgcolor='black',
),
title='Isosurface Visualization',
font=dict(color='white'),
)
fig.show()
fig.write_html("output.html", auto_open=True)
Code explanation
Line 1–2: We import our necessary modules,
plotly.graph_objectsasgo, andnumpyasnp.Line 4: We create our 3D coordinate grids
X,Y, andZusingnp.mgrid. Each grid spans from -5 to 5 i.e., along the axis, and contains 40 points.Line 6: We can create our own values to display different kinds of plots. Here,
valuesare calculated as a combination ofmultiplied by the exponential decay of with a decay factor of -0.2. Lines 8–19: We create a Figure object named
figand add an Isosurface plot to it usinggo.Isosurface(). To correctly display our plot, we specify flattened x, y, and z coordinates from the grids and the flattened ‘values’ array. Our parameters are:isominandisomaxdefine the range of displayed values.capshides the caps of the isosurfaces.slices_zandslices_ydefine slices along the Z and Y axes.colorscaledetermines the color mapping. For instance, 'electric'.
Lines 21–30: Next, we update the figure's layout through
fig.update_layout(). Within thesceneparameter, we customize the axis titles, set the background color to black, and set the font color to white.Line 32: Finally, we display our plot using
fig.show().
Demonstration
This is how an isosurface plot with more customizations can look like.
Multiple surfaces
We can simply add more surfaces using the parameter surface_count and defining the number of surfaces we want in the plot.
import plotly.graph_objects as go
import numpy as np
X, Y, Z = np.mgrid[-5:5:40j, -5:5:40j, -5:5:40j]
values = (X**2 + Y**2 + Z**2) * np.sin(5 * np.sqrt(X**2 + Y**2 + Z**2))
fig = go.Figure(data=go.Isosurface(
x=X.flatten(),
y=Y.flatten(),
z=Z.flatten(),
value=values.flatten(),
isomin=-100,
isomax=100,
surface_count=3,
caps=dict(x_show=False, y_show=False),
colorscale='aggrnyl',
))
fig.update_layout(
scene=dict(
xaxis_title='X Axis',
yaxis_title='Y Axis',
zaxis_title='Z Axis',
bgcolor='black',
),
title='Isosurface Visualization',
font=dict(color='white'),
)
fig.show()
fig.write_html("output.html", auto_open=True)
Demonstration
This is how an isosurface with multiple surfaces looks like.
Opacity
We can change the opacity of the plot to display the layers within vividly. This can be done using the opacity keyword.
import plotly.graph_objects as go
import numpy as np
X, Y, Z = np.mgrid[-5:5:40j, -5:5:40j, -5:5:40j]
values = X * X * 0.5 + Y * Y + Z * Z * 2
fig = go.Figure(data=go.Isosurface(
x=X.flatten(),
y=Y.flatten(),
z=Z.flatten(),
value=values.flatten(),
opacity=0.6,
isomin=10,
isomax=50,
surface_count=3,
caps=dict(x_show=False, y_show=False),
colorscale='hot',
))
fig.update_layout(
scene=dict(
xaxis_title='X Axis',
yaxis_title='Y Axis',
zaxis_title='Z Axis',
bgcolor='black',
),
margin=dict(l=0, r=0, b=0, t=0),
title='Isosurface Visualization',
font=dict(color='white'),
)
fig.show()
fig.write_html("output.html", auto_open=True)Demonstration
This is how an isosurface with multiple surfaces and lesser opacity looks like.
Adding slices to the plot
Here, we add two more parameters. slices_z and slices_y parameters add cross-sectional slices to the isosurface plot along the Z and Y axes, respectively. This allows the visualization of the isosurface's internal structure at specific axis positions.
import plotly.graph_objects as go
import numpy as np
X, Y, Z = np.mgrid[-5:5:40j, -5:5:40j, -5:5:40j]
values = np.sin(np.sqrt(X**2 + Y**2 + Z**2)) + np.cos(np.sqrt(X**2 + Y**2 + Z**2)) + (X**2 + Y**2 + Z**2) * 0.1
fig = go.Figure(data=go.Isosurface(
x=X.flatten(),
y=Y.flatten(),
z=Z.flatten(),
value=values.flatten(),
isomin=-2,
isomax=3,
surface_fill=0.5,
caps=dict(x_show=False, y_show=False),
slices_z=dict(show=True, locations=[-1, -3]),
slices_y=dict(show=True, locations=[0]),
colorscale='RdBu',
))
fig.update_layout(
scene=dict(
xaxis_title='X Axis',
yaxis_title='Y Axis',
zaxis_title='Z Axis',
bgcolor='black',
),
title='Complex Isosurface Visualization',
font=dict(color='white'),
)
fig.show()
fig.write_html("output.html", auto_open=True)Demonstration
This is how an isosurface with multiple slices looks like.
Use cases of isosurface plots
There are various ways isosurface plots can be aligned with real-life data. Let's explore a few use cases.
Medical Imaging
Isosurface plots can show detailed anatomical structures from MRI and CT scans.
Geophysics
Isosurface plots can assist in mapping subsurface formations by using seismic or gravity data.
Fluid Dynamics
Isosurface plots are great for visualizing fluid flow around objects and understanding hydrodynamic processes.
Simulations
Isosurface plots can be used in climate modeling and particle physics.
What parameter allows us to add multiple surfaces to our isosurface plot in Plotly?
Free Resources