Как реализовать цилиндрическую сетку для трехмерного графика?Python

Программы на Python
Ответить
Anonymous
 Как реализовать цилиндрическую сетку для трехмерного графика?

Сообщение Anonymous »

Я хочу построить трехмерную кривую, показывающую сетку XY в полярных координатах. Вот эскиз
Изображение

и мой скрипт, который его сгенерировал:

Код: Выделить всё

from math import cos, cosh, floor, pi, sin, sinh

import matplotlib.pyplot as plt
import numpy as np
from scipy.spatial.transform import Rotation

def set_axes_equal_3d(ax):
# https://stackoverflow.com/a/13701747/31611660
lims = [ax.get_xlim3d(), ax.get_ylim3d(), ax.get_zlim3d()]
ranges = [x[1] - x[0] for x in lims]
mids = [np.mean(x) for x in lims]
plot_radius = 0.5 * max([abs(x) for x in ranges])
for setl, r, m in zip([ax.set_xlim3d, ax.set_ylim3d, ax.set_zlim3d], ranges, mids):
setl(m - np.sign(r) * plot_radius, m + np.sign(r) * plot_radius)

rot = Rotation.from_euler("ZXZ", (25, 75, 75))
proj = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 0]])
points = rot.apply([[1.0 * cosh(a), 2 * sinh(a), 0] for a in np.arange(-3, 3, 0.01)])
points += np.array([0, 0, -min(points[:, 2])])
circ = np.array([[cos(a), sin(a), 0] for a in np.arange(-pi, pi, 0.01)])
fig = plt.figure(figsize=(10, 8))
ax = fig.add_subplot(111, projection="3d")
# trajectory
ax.plot(*zip(points.T), linewidth=3)
# projection
ax.plot(*zip(proj.dot(points.T)), "--", linewidth=1)
# vertical guidelines
for idx in range(0, len(points), floor(len(points) / 6)):
ax.plot(
[points[idx][0]] * 2,
[points[idx][1]] * 2,
[0, points[idx][2]],
"--",
linewidth=1,
)
# polar grid of poverty
for r in [10, 15, 20, 25]:
ax.plot(*zip(*(r * circ)), ":", linewidth=0.5, color="gray")
for ang in np.arange(0, 360, 30) * pi / 180:
ax.plot(
[0, 25 * cos(ang)], [0, 25 * sin(ang)], [0, 0], ":", linewidth=0.5, color="gray"
)
# config
ax.set_xlabel("X")
ax.set_ylabel("Y")
ax.set_zlabel("Z")
ax.set_title("Simple 3D Hyperbola")
set_axes_equal_3d(ax)
ax.axis("off")
plt.show()
Мне бы хотелось, чтобы сетка в плоскости XY была такой, как эта, которую я адаптировал из https://dev.to/labex/custom-grid-and-po ... otlib-3e2m. Я хочу, чтобы сетка была обрезана по границам оси и имела метки для расстояния и угла, как здесь. Делительные отметки выглядят великолепно, но в этом нет необходимости.
Изображение

Вот этот скрипт

Код: Выделить всё

from math import cosh, sinh

import matplotlib.pyplot as plt
import numpy as np
from matplotlib.projections import PolarAxes
from matplotlib.transforms import Affine2D
from mpl_toolkits.axisartist import HostAxes, angle_helper
from mpl_toolkits.axisartist.grid_helper_curvelinear import \
GridHelperCurveLinear
from scipy.spatial.transform import Rotation

# -- set up for Polar grid
# https://dev.to/labex/custom-grid-and-polar-projection-in-matplotlib-3e2m
tr = Affine2D().scale(np.pi / 180, 1) + PolarAxes.PolarTransform()
extreme_finder = angle_helper.ExtremeFinderCycle(
nx=20,
ny=20,
lon_cycle=360,
lat_cycle=None,
lon_minmax=None,
lat_minmax=(0, np.inf),
)
grid_locator1 = angle_helper.LocatorDMS(12)
tick_formatter1 = angle_helper.FormatterDMS()
# Create GridHelperCurveLinear object
grid_helper = GridHelperCurveLinear(
tr,
extreme_finder=extreme_finder,
grid_locator1=grid_locator1,
tick_formatter1=tick_formatter1,
)
# compute hyperbola
rot = Rotation.from_euler("ZXZ", (25, 75, 75))
points = rot.apply([[1.0 * cosh(a), 2 * sinh(a), 0] for a in np.arange(-3, 3, 0.01)])
fig = plt.figure(figsize=(10, 8))
ax = fig.add_subplot(111, axes_class=HostAxes, grid_helper=grid_helper)
# trajectory
ax.plot(*points.T[:2], linewidth=3)
ax.set_xlabel("X")
ax.set_ylabel("Y")
# Make ticklabels of right and top axis visible
ax.axis["right"].major_ticklabels.set_visible(True)
ax.axis["top"].major_ticklabels.set_visible(True)
# Let right axis show ticklabels for 1st coordinate (angle)
ax.axis["right"].get_helper().nth_coord_ticks = 0
# Let bottom axis show ticklabels for 2nd coordinate (radius)
ax.axis["bottom"].get_helper().nth_coord_ticks = 1
# Add grid lines
ax.grid(True, zorder=0, color="lightgrey", linewidth=0.5)
ax.set_aspect("equal")
plt.show()
Я хочу создать трехмерный линейный график, но заменю набросок полярной сетки гораздо более привлекательной полярной сеткой, показанной выше. Я просмотрел документацию matplotlib и не увидел никаких упоминаний об использовании 3D-графиков на https://matplotlib.org/stable/gallery/a ... _grid.html или о настройке 3D-сетки на странице https://matplotlib.org/stable/api/_as_g ... xes3D.grid

Подробнее здесь: https://stackoverflow.com/questions/798 ... -a-3d-plot
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Python»