Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 182238c

Browse filesBrowse files
authored
Merge pull request #28283 from meeseeksmachine/auto-backport-of-pr-28280-on-v3.9.x
Backport PR #28280 on branch v3.9.x (DOC: Add an example for 2D images in 3D plots)
2 parents 4739e48 + bb1dcc3 commit 182238c
Copy full SHA for 182238c

File tree

Expand file treeCollapse file tree

1 file changed

+88
-0
lines changed
Filter options
Expand file treeCollapse file tree

1 file changed

+88
-0
lines changed
+88Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
"""
2+
===============
3+
2D images in 3D
4+
===============
5+
6+
This example demonstrates how to plot 2D color coded images (similar to
7+
`.Axes.imshow`) as a plane in 3D.
8+
9+
Matplotlib does not have a native function for this. Below we build one by relying
10+
on `.Axes3D.plot_surface`. For simplicity, there are some differences to
11+
`.Axes.imshow`: This function does not set the aspect of the Axes, hence pixels are
12+
not necessarily square. Also, pixel edges are on integer values rather than pixel
13+
centers. Furthermore, many optional parameters of `.Axes.imshow` are not implemented.
14+
15+
Multiple calls of ``imshow3d`` use independent norms and thus different color scales
16+
by default. If you want to have a single common color scale, you need to construct
17+
a suitable norm beforehand and pass it to all ``imshow3d`` calls.
18+
19+
A fundamental limitation of the 3D plotting engine is that intersecting objects cannot
20+
be drawn correctly. One object will always be drawn after the other. Therefore,
21+
multiple image planes can well be used in the background as shown in this example.
22+
But this approach is not suitable if the planes intersect.
23+
"""
24+
25+
import matplotlib.pyplot as plt
26+
import numpy as np
27+
28+
from matplotlib.colors import Normalize
29+
30+
31+
def imshow3d(ax, array, value_direction='z', pos=0, norm=None, cmap=None):
32+
"""
33+
Display a 2D array as a color-coded 2D image embedded in 3d.
34+
35+
The image will be in a plane perpendicular to the coordinate axis *value_direction*.
36+
37+
Parameters
38+
----------
39+
ax : Axes3D
40+
The 3D Axes to plot into.
41+
array : 2D numpy array
42+
The image values.
43+
value_direction : {'x', 'y', 'z'}
44+
The axis normal to the image plane.
45+
pos : float
46+
The numeric value on the *value_direction* axis at which the image plane is
47+
located.
48+
norm : `~matplotlib.colors.Normalize`, default: Normalize
49+
The normalization method used to scale scalar data. See `imshow()`.
50+
cmap : str or `~matplotlib.colors.Colormap`, default: :rc:`image.cmap`
51+
The Colormap instance or registered colormap name used to map scalar data
52+
to colors.
53+
"""
54+
if norm is None:
55+
norm = Normalize()
56+
colors = plt.get_cmap(cmap)(norm(array))
57+
58+
if value_direction == 'x':
59+
nz, ny = array.shape
60+
zi, yi = np.mgrid[0:nz + 1, 0:ny + 1]
61+
xi = np.full_like(yi, pos)
62+
elif value_direction == 'y':
63+
nx, nz = array.shape
64+
xi, zi = np.mgrid[0:nx + 1, 0:nz + 1]
65+
yi = np.full_like(zi, pos)
66+
elif value_direction == 'z':
67+
ny, nx = array.shape
68+
yi, xi = np.mgrid[0:ny + 1, 0:nx + 1]
69+
zi = np.full_like(xi, pos)
70+
else:
71+
raise ValueError(f"Invalid value_direction: {value_direction!r}")
72+
ax.plot_surface(xi, yi, zi, rstride=1, cstride=1, facecolors=colors, shade=False)
73+
74+
75+
fig = plt.figure()
76+
ax = fig.add_subplot(projection='3d')
77+
ax.set(xlabel="x", ylabel="y", zlabel="z")
78+
79+
nx, ny, nz = 8, 10, 5
80+
data_xy = np.arange(ny * nx).reshape(ny, nx) + 15 * np.random.random((ny, nx))
81+
data_yz = np.arange(nz * ny).reshape(nz, ny) + 10 * np.random.random((nz, ny))
82+
data_zx = np.arange(nx * nz).reshape(nx, nz) + 8 * np.random.random((nx, nz))
83+
84+
imshow3d(ax, data_xy)
85+
imshow3d(ax, data_yz, value_direction='x', cmap='magma')
86+
imshow3d(ax, data_zx, value_direction='y', pos=ny, cmap='plasma')
87+
88+
plt.show()

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.