如何在Matplotlib中将3D箭头的箭头旋转?

10

我试图使用Python和Matplotlib复制以下图表。

Plot I want to replicate

然而,我所能够产出的最好结果如下:

My attempt

主要问题在于箭头不在平面内,即使我对整个图的质量感到不满意。我已经寻找了在三维图中使用二维箭头quiver的解决方案,但我没有找到任何有用的信息。是否有其他方法实现平面内箭头?
import numpy as np
from matplotlib import pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import cm

params = {
   'font.family' : 'serif',
   'mathtext.fontset': 'stix',
   'axes.labelsize': 13,
   'legend.fontsize': 8,
   'xtick.labelsize': 13,
   'ytick.labelsize': 13,
   'text.usetex': True,
   'figure.figsize': [10, 5]
   }


plt.rcParams.update(params)

plt.close('all')


x_ax = np.linspace(-10, 10, 24)
y_ax = np.linspace(-10, 10, 24)

x, y = np.meshgrid(x_ax, y_ax, indexing='ij')

r = np.sqrt(x**2 + y**2)

j_x = -y/r*(- np.exp(-np.abs(r)) + np.exp(-np.abs(r)/2) )*2
j_y = +x/r*(- np.exp(-np.abs(r)) + np.exp(-np.abs(r)/2) )*2

#c = np.arctan2(x, -y)
c = np.sqrt(j_x**2 + j_y**2)
c = (c.ravel() - c.min()) / c.ptp()
c = np.concatenate((c, np.repeat(c, 2)))
c = cm.jet(c)
#c = plt.cm.hsv(c)

fig = plt.figure()
ax = fig.gca(projection='3d')

ax.quiver(x, y, 0, j_x, j_y, 0, colors=c, length=1.2, pivot='middle')


t = np.linspace(-10, 10, 200)

psi = 1 - np.exp(-np.abs(t))
b = np.exp(-t**2)
j_abs = np.abs(t)*np.exp(-t**2)*2
#j_abs = (- np.exp(-np.abs(t)) + np.exp(-np.abs(t)/2) )*2

ax.plot(t, psi, zs=0, zdir='y', label=r"$|\psi|$")
ax.plot(t, b, zs=0, zdir='y', label=r"$|\vec B|$")
ax.plot(t, j_abs, zs=0, zdir='y', label=r"$|\vec j|$")

ax.legend()

ax.set_proj_type('ortho')
ax.set_axis_off()

ax.set_zlim([-0.2, 1.4])
ax.view_init(elev=45, azim=90)
ax.dist=5
fig.savefig("vortex.pdf", bbox_inches="tight")
1个回答

0
也许mplot3d不是在这里使用的正确工具,因为这不是一个真正的三维图形,而只是两个二维图形的组合。考虑以下方法:
  1. 在二维平面上绘制底部箭头,就像从中心向上看一样,并将该图形保存为正方形图像。
  2. 创建另一幅图像,作为第一幅图像的投影,从所需的角度查看。例如,使用OpenCV中的 warpPerspective()
  3. 创建一个新的图形,包含三个线图,在其中插入来自步骤2的图像,使用plt.imshow()
我猜这大致是如何制作上面的原始图形的。它会处理箭头在平面内的效果,以及前景中的箭头比背景中的箭头更大等效果。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接