遵循给定线的3D栏图
我想在3D中绘制一个条图。我知道如何使用以下代码做到这一点:
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import numpy as np
fig = plt.figure(figsize=(10,10))
ax = fig.add_subplot(111, projection='3d')
nbins = 50
# for c, z in zip(['r', 'g', 'b', 'y'], [30, 20, 10, 0]):
ys = np.random.normal(loc=10, scale=10, size=2000)
hist, bins = np.histogram(ys, bins=nbins)
xs = (bins[:-1] + bins[1:])/2
ax.bar(xs, hist, zs=30, zdir='y', color='r', ec='r', alpha=0.8)
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
plt.show()
这将呈现出类似的内容: https:// i。 sstatic.net/kk2if.png
但是,我的目标是使栏图遵循我作为参数的行。例如,这里的参数zdir ='y'使图具有其当前方向。理想情况下,我想传递一个使图遵循给定线路的参数,例如y = 2x+1。
有人可以帮助达到所需的结果吗?
I want to draw a bar plot in 3d. I know how to do that using the following code:
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
import numpy as np
fig = plt.figure(figsize=(10,10))
ax = fig.add_subplot(111, projection='3d')
nbins = 50
# for c, z in zip(['r', 'g', 'b', 'y'], [30, 20, 10, 0]):
ys = np.random.normal(loc=10, scale=10, size=2000)
hist, bins = np.histogram(ys, bins=nbins)
xs = (bins[:-1] + bins[1:])/2
ax.bar(xs, hist, zs=30, zdir='y', color='r', ec='r', alpha=0.8)
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_zlabel('Z')
plt.show()
This will render something like this: https://i.sstatic.net/KK2If.png
However, my goal is to make the bar plot follows a line that I give as parameter. For example here, the parameter zdir='y' makes the plot have its current direction. Ideally I want to pass a parameter that makes the plot follows a given line for example y=2x+1.
Could someone help arrive at the desired result?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
实现这一目标的一种方法是使用
poly3dcollection
:想法是计算每个条的坐标和方向,然后将其添加到图中。可以从3D空间中的矩形开始并应用适当的转换矩阵开始计算每个条的位置和方向。
如果要更改
曲线
,也需要更改barwidth
。编辑解释正在发生的事情:
考虑一个带有4个顶点的通用矩形:左下,右下,右下,右上,左上,左上。为简单起见,让我们修复宽度=高度= 1。然后,我们考虑一个参考系统X,Y,Z,然后绘制此矩形。顶点的坐标为:左下(-0.5,0,0),右下(0.5,0,0),右上(0.5,0,1)和左上(-0.5,0,1)。请注意,该矩形以X方向为中心。如果我们将其移至x = 2,则将其以该位置为中心。您可以在
rect
中看到上述坐标:为什么此变量的第四列填充了?这是能够将翻译矩阵应用于顶点的数学技巧。让我们来谈谈变换矩阵(Wikipedia对此有一个不错的页面))。再次考虑我们的通用矩形:我们可以将其缩放,旋转并翻译它以在我们想要的位置和方向上获得一个新的矩形。
因此,上面的代码定义了每个转换的功能,
转换,比例,旋转
。事实证明,我们可以将多个转换矩阵乘以总体转换:这就是transformation_matrix
做的,它将上述转换结合到一个矩阵中。最后,我使用
apply_transform
将转换矩阵应用于通用矩形:这将在指定的位置/方向上计算新矩形顶点的坐标,该位置/方向,指定的大小(宽度,高度) 。One way to achieve that is by using
Poly3DCollection
: the idea is to compute the coordinates and orientation of each bar, then add it to the plot.The position and orientation of each bar can be computed starting from a rectangle in 3D space and applying the appropriate transformation matrix.
If you are going to change the
curve
, you will also need to change the barwidth
.EDIT to explain what is going on:
Consider a generic rectangle with 4 vertices: bottom left, bottom right, top right, top left. For simplicity, let's fix width=height=1. Then we consider a reference system x,y,z and we draw this rectangle. The coordinates of vertices are: bottom left (-0.5, 0, 0), bottom right (0.5, 0, 0), top right (0.5, 0, 1) and top left (-0.5, 0, 1). Note that this rectangle is centered around the zero in the x direction. If we move it to x=2, then it will be centered at that location. You can see the above coordinates in
rect
: why does this variable has a fourth column filled with ones? That's a mathematical trick to be able to apply a translation matrix to the vertices.Let's talk about transformation matrices (wikipedia has a nice page about it). Consider again our generic rectangle: we can scale it, rotate it and translate it to get a new rectangle in the position and orientation we want.
So, the code above defines a function for each transformation,
translate, scale, rotate
. Turns out that we can multiply together multiple transformation matrices to get an overall transformation: that's whattransformation_matrix
does, it combines the aforementioned transformations into a single matrix.Finally, I used
apply_transform
to apply the transformation matrix to the generic rectangle: this will compute the coordinates of the vertices of the new rectangle, in the specified position/orientation with the specified size (width, height).