Closed imakn634 closed 2 months ago
I'm afraid there is nothing I can do. This is a Matplotlib problem, and it is the very reason I developed multiple backends, because Matplotlib sucks at 3D plotting. To be honest, there is no perfect plotting library in the Python ecosystem, each one has its pros and cons, and very few produces good results with 3D plotting.
This plotting module exponses PlotlyBackend
and K3DBackend
which are usually superior to Matplotlib when it comes to 3D plotting. However, Plotly 3D doesn't have the notion of "arrows", it just shows cones, which makes it hardly suitable to your use case.
I'm going to show you the same example with K3D Jupyter. In order to use it, you either install the full plotting module as mentioned in the installation page, or you just install the necessary requirements:
pip install k3d colorcet
or:
conda install -c conda-forge k3d
conda install -c conda-forge colorcet
I'm going to mention first its limitations, which are particularly important.
tx=, ty=, tz=
(more on this later).import k3d
from sympy import *
from spb import *
var("t")
graphics(
line_parametric_3d(
cos(t), sin(t), 0.1*t, (t, 0, 4*pi),
use_cm=True,color_func = sin(t), colorbar=False,
rendering_kw={"width": 0.02, "color_map": k3d.matplotlib_color_maps.Autumn}
),
arrow_3d(
(0, 0, -1), (0, 0, 3),
rendering_kw={"origin_color": 0x0000ff, "head_color": 0x0000ff, "line_width": 0.02, "head_size": 2}
),
backend=KB
)
In the top right of the picture, you see "K3D panel", which can be used to further customize the plot, after it has been created. Particularly useful is the "Objects" tab, where you can see the objects that are inside the plot, and their respective keyword arguments (eventually, to be used in the rendering_kw=
parameter).
For objects that requires colormaps, you have a great choice of colormaps. Just execute one by one the following commands to see the output.
dir(k3d.basic_color_maps)
dir(k3d.matplotlib_color_maps)
dir(k3d.paraview_color_maps)
I've see that your parametric curve is scaled on the z-direction. Let's suppose it wasn't:
graphics(
line_parametric_3d(
cos(t), sin(t), t, (t, 0, 4*pi),
use_cm=True,color_func = sin(t), colorbar=False,
rendering_kw={"width": 0.02, "color_map": k3d.matplotlib_color_maps.Autumn}
),
arrow_3d(
(0, 0, -1), (0, 0, 15),
rendering_kw={"origin_color": 0x0000ff, "head_color": 0x0000ff, "line_width": 0.02, "head_size": 2}
),
backend=KB
)
Here you can see the limitations of the equal aspect ratio on all axis: the visualization is stretched too much on the z-axis, which also causes the grids to be weirdly stretched. In this case I usually set the transformation keyword arguments in order to make the plot more readable:
z_transform = lambda z: z/10
graphics(
line_parametric_3d(
cos(t), sin(t), t, (t, 0, 4*pi),
use_cm=True,color_func = sin(t), colorbar=False,
rendering_kw={"width": 0.02, "color_map": k3d.matplotlib_color_maps.Autumn},
tz=z_transform
),
arrow_3d(
(0, 0, -1), (0, 0, 15),
rendering_kw={"origin_color": 0x0000ff, "head_color": 0x0000ff, "line_width": 0.02, "head_size": 2},
tz=z_transform
),
backend=KB, grid=False
)
Thank you very much for the detailed explanation. I now understand this is a Matplotlib problem. K3D looks interesting. I will try it. Thanks again!
Sorry for a long post. It's nice to plot
line_parametric_3d()
withuse_cm=True
:(So far I couldn't plot it using Matplotlib
plt.plot()
.)For educational purpose, I want to draw the spiral motion in the uniform magnetic field, something like this:
The background part of the trajectory is denoted by
zorder
:0, whereas the foreground part is byzorder
:10. OK, it works.However, when I set
use_cm=True
,zorder
seems not to work properly.It would be nicer if
use_cm=True
still respectszorder
...