#python #matplotlib
#python #matplotlib
Вопрос:
Обычно на 2D-графике matplotlib вы получаете 1-й квандрант декартовой плоскости с линиями осей в левой и нижней областях графика. Поскольку я строю график для математических заметок, мне нужен макет с четырьмя квадрантами, который можно выполнить с помощью этого:
x = np.arange(-10, 10, 0.1)
y = np.cos(x)
f = plt.figure()
ax = f.add_subplot(1, 1, 1)
ax.spines['left'].set_position('center')
ax.spines['right'].set_color('none')
ax.spines['bottom'].set_position('center')
ax.spines['top'].set_color('none')
ax.plot(x, y, c='black', linewidth=1)
ax.fill_between(x, y, where=(x > -1e-10) amp; (x < np.pi), color='gray')
ax.set_xbound(-2*np.pi, 2*np.pi)
ax.set_ybound(-3, 3)
f.suptitle("Area under a cosine function", size='x-large', weight='bold')
f.show()
Теперь я хочу сделать это с помощью 3D-графиков, где все линии осей x, y, z пересекаются в начале координат, так что «шипы» (я знаю, что объекты Axes3D на самом деле не имеют шипов) разделяют пространство на 8 квадрантов. Как я могу этого добиться?
РЕДАКТИРОВАТЬ: текущий код 3D-графика:
x = np.arange(-5, 5)
y = np.arange(-5, 5)
z = np.arange(-5, 5)
class Arrow3D(FancyArrowPatch):
def __init__(self, xs, ys, zs, *args, **kwargs):
FancyArrowPatch.__init__(self, (0,0), (0,0), *args, **kwargs)
self._verts3d = xs, ys, zs
def draw(self, renderer):
xs3d, ys3d, zs3d = self._verts3d
xs, ys, zs = proj3d.proj_transform(xs3d, ys3d, zs3d, renderer.M)
self.set_positions((xs[0],ys[0]),(xs[1],ys[1]))
FancyArrowPatch.draw(self, renderer)
f = plt.figure()
ax = f.add_subplot(1, 1, 1, projection='3d')
ax.set_axis_off()
ax.add_artist(Arrow3D([-5, 5], [0, 0], [0, 0]))
ax.add_artist(Arrow3D([0, 0], [-5, 5], [0, 0]))
ax.add_artist(Arrow3D([0, 0], [0, 0], [-5, 5]))
ax.scatter(x, y, z)
f.show()
Проблема теперь в том, что данные и данные, похоже, не выровнены; оси установлены на (я думаю) от -5 до 5 в каждом направлении, но данные, также от -5 до 5, выглядят так, как будто они превышают «границы» оси?
Комментарии:
1. Вы можете отключить оси с
ax3d.set_axis_off()
помощью, а затем создать свои собственные линии осей сax3d.add_artist(Arrow3D())
помощью .2.
Arrow3D
Из какого класса? Кажется, я не могу его найти.
Ответ №1:
Попробуйте этот фрагмент кода, поместив его после ax.scatter()
:
ax.add_artist(Arrow3D([-5, 5], [0, 0], [0, 0], mutation_scale=20, lw=1, arrowstyle="-|>", color="r"))
ax.add_artist(Arrow3D([0, 0], [-5, 5], [0, 0], mutation_scale=20, lw=1, arrowstyle="-|>", color="b"))
ax.add_artist(Arrow3D([0, 0], [0, 0], [-5, 5], mutation_scale=20, lw=1, arrowstyle="-|>", color="g"))
# set viewing angle
ax.azim = 40 # z rotation (default=270)
ax.elev = 25 # x rotation (default=0)
ax.dist = 10 # zoom (define perspective)
Это заменяет все ax.add_artist()
в вашем коде.