-
-
Notifications
You must be signed in to change notification settings - Fork 8.1k
Closed as not planned
Labels
Description
Bug summary
Using vertical_axis="y" in ax.view_init() results in wrong plot.
Code for reproduction
import numpy as np
import matplotlib.pyplot as plt
def cuboid_data(center, extent):
# Implementation is based on the following StackOverflow posts:
# https://stackoverflow.com/a/49281004
# https://stackoverflow.com/a/35978146
# suppose axis direction: x: to left; y: to inside; z: to upper
# get the (left, outside, bottom) point
o = center
# get the length, width, and height
l, w, h = extent
x = [[o[0], o[0] + l, o[0] + l, o[0], o[0]], # x coordinate of points in bottom surface
[o[0], o[0] + l, o[0] + l, o[0], o[0]], # x coordinate of points in upper surface
[o[0], o[0] + l, o[0] + l, o[0], o[0]], # x coordinate of points in outside surface
[o[0], o[0] + l, o[0] + l, o[0], o[0]]] # x coordinate of points in inside surface
y = [[o[1], o[1], o[1] + w, o[1] + w, o[1]], # y coordinate of points in bottom surface
[o[1], o[1], o[1] + w, o[1] + w, o[1]], # y coordinate of points in upper surface
[o[1], o[1], o[1], o[1], o[1]], # y coordinate of points in outside surface
[o[1] + w, o[1] + w, o[1] + w, o[1] + w, o[1] + w]] # y coordinate of points in inside surface
z = [[o[2], o[2], o[2], o[2], o[2]], # z coordinate of points in bottom surface
[o[2] + h, o[2] + h, o[2] + h, o[2] + h, o[2] + h], # z coordinate of points in upper surface
[o[2], o[2], o[2] + h, o[2] + h, o[2]], # z coordinate of points in outside surface
[o[2], o[2], o[2] + h, o[2] + h, o[2]]] # z coordinate of points in inside surface
return np.asarray(x), np.asarray(y), np.asarray(z)
def annotate_patient_axes(ax):
xmin, xmax = ax.get_xlim()
ax.set_xticks((xmin, xmax))
ax.set_xticklabels(("R", "L"))
ax.set_xlabel("x", fontsize=20)
ymin, ymax = ax.get_ylim()
ax.set_yticks((ymin, ymax))
ax.set_yticklabels(("A", "P"))
ax.set_ylabel("y", fontsize=20)
zmin, zmax = ax.get_zlim()
ax.set_zticks((zmin, zmax))
ax.set_zticklabels(("I", "S"))
ax.set_zlabel("z", fontsize=20)
def plot_patient(ax):
# start position, extent, color
parts = {
"right_arm": ((0, 1, 12), (1, 1, 9), "gray"),
"left_arm": ((7, 1, 12), (1, 1, 9), "gray"),
"body": ((1, 0, 9), (6, 3, 12), "blue"),
"left_leg": ((2, 1, 0), (1, 1, 9), "gray"),
"right_leg": ((5, 1, 0), (1, 1, 9), "gray"),
"head": ((2, 1, 21), (4, 1, 5), "orange"),
"nose": ((3.5, 1, 22), (1, -2, 1), "red"),
}
for val in parts.values():
start, extent, color = val
X, Y, Z = cuboid_data(start, extent);
ax.plot_surface(X, Y, Z, color=color, edgecolor="black")
ax.set_box_aspect((1, 1, 1))
# Axis labels.
ax.set_xlim((-5, 14)) # Patient occupies (0, 9) in x.
ax.set_ylim((-6, 8)) # Patient occupies (-1, 3) in y.
ax.set_zlim((-5, 29)) # Patient occupies (0, 24) in z.
annotate_patient_axes(ax)
def plot_patient_perspectives():
fig = plt.figure(figsize=(2*8, 2*4.5))
ax = fig.add_subplot(221, projection="3d")
ax2 = fig.add_subplot(222, projection="3d")
ax3 = fig.add_subplot(223, projection="3d")
ax4 = fig.add_subplot(224, projection="3d")
plot_patient(ax)
plot_patient(ax2)
plot_patient(ax3)
plot_patient(ax4)
# See documentation for meaning of angles:
# https://matplotlib.org/stable/api/_as_gen/mpl_toolkits.mplot3d.axes3d.Axes3D.view_init.html
# Top view on patient.
ax.set_title("Top view", fontsize=20)
ax.view_init(-90, 0, vertical_axis="y")
# Side view on patient.
ax2.set_title("Side view", fontsize=20)
ax2.view_init(180, -90, vertical_axis="y")
# Foot view on patient.
ax3.set_title("Foot view", fontsize=20)
ax3.view_init(180, 0, vertical_axis="y")
# Perspective view on patient.
ax4.set_title("Perspective view", fontsize=20)
ax4.view_init(210, -70, vertical_axis="y")
fig.tight_layout()
return fig, [ax, ax2, ax3, ax4]
fig, axes = plot_patient_perspectives();Actual outcome
The bottom right plot misplaces the objects in 3D space and is not consistent with the axis-aligned projections.
Expected outcome
Consistent views.
Additional information
No response
Operating system
Linux
Matplotlib Version
3.8.3
Matplotlib Backend
module://matplotlib_inline.backend_inline
Python version
3.9.18
Jupyter version
No response
Installation
conda