4D绘图,用单一颜色描述第四维,并用线连接。

huangapple go评论83阅读模式
英文:

4D plots with single colour describing the 4th dimension and connected by line

问题

I have been searching the internet for the past couple of days and I have not seen any solution. I will be grateful if someone can please have a look.

我已经在过去的几天里在互联网上搜索了,但没有找到任何解决方案。如果有人能够看一下,我将不胜感激。

I am trying to plot a 4D plot to show wind direction variation at a given longitude, latitude, and altitude.

我正在尝试绘制一个四维图,以显示在给定的经度、纬度和高度下风向的变化。

I see a jump in my graph when the object moves from one altitude to the other. Is it possible to connect the points with a line? to indicate that there is a movement.

当物体从一个高度移动到另一个高度时,我在我的图表中看到一个跳跃。是否可以用一条线连接这些点?以指示存在运动。

The sample code is shown below:

示例代码如下:

import numpy as np
from matplotlib import pyplot as plt

lon = np.array([278.6695, 278.67, 278.672265])
lat = np.array([48.476151, 48.472578621119, 48.45994295])
Z = np.array([20000, 26502.51477, 26501.65171])
distance = np.array([72.63856248, 70, 60])

fig = plt.figure(6)
ax = fig.add_subplot(111, projection='3d')
img = ax.scatter(lon, lat, Z, c=distance, cmap='inferno', alpha=1)
fig.colorbar(img)

ax.set_xlabel('longitude [Deg]')
ax.set_ylabel('latitude [Deg]')
ax.set_zlabel('Altitude [Km]')

plt.show()

4D绘图,用单一颜色描述第四维,并用线连接。

我的结果当我绘制我的全部数据时
4D绘图,用单一颜色描述第四维,并用线连接。

当我绘制所有数据时的结果

4D绘图,用单一颜色描述第四维,并用线连接。

所期望的图表

英文:

I have been searching the internet for the past couple of days and I have not seen any solution. I will be grateful if someone can please have a look.

I am trying to plot a 4D plot to show wind direction variation at a given longitude, latitude, and altitude.

I see a jump in my graph when the object moves from one altitude to the other. Is it possible to connect the points with a line? to indicate that the is a movement.

The sample code is shown below:

import numpy as np
from matplotlib import pyplot as plt

lon = np.array([278.6695, 278.67,278.672265 ])
lat = np.array([48.476151, 48.472578621119, 48.45994295 ])
Z  = np.array([20000, 26502.51477,26501.65171])
distance = np.array([72.63856248, 70, 60 ])

fig = plt.figure(6)
ax = fig.add_subplot(111, projection='3d')
img = ax.scatter(lon, lat, Z, c=distance, cmap='inferno', alpha=1)
fig.colorbar(img)

ax.set_xlabel('longitude [Deg]')
ax.set_ylabel('latitude [Deg]')
ax.set_zlabel('Altitude [Km]')


plt.show()

4D绘图,用单一颜色描述第四维,并用线连接。

My result when I plot my whole data
4D绘图,用单一颜色描述第四维,并用线连接。

Secondly, I would like to show the distance using just one colour (i.e. Black ) instead of using multiple colours. My end goal is to have a plot like this

4D绘图,用单一颜色描述第四维,并用线连接。

答案1

得分: 1

以下是翻译好的部分:

Answer

这个答案展示了如何创建你所要求的最终图表。单一颜色和连接线的两个请求都是非常可能的。对你所期望的图像进行谷歌搜索,最初是一个“animation”,这是我也包括的另一部分。

Example Output

这是一个显示你最终目标的图表。复制图表的代码如下。

4D绘图,用单一颜色描述第四维,并用线连接。

也可以创建一个随时间变化的图表。请注意,随着距离起始位置的增加,线条的颜色也会发生变化。这个特性很容易禁用。

4D绘图,用单一颜色描述第四维,并用线连接。

Code

这是用于静态和动画图表的一些设置代码。

# 必要的导入
import numpy as np
import matplotlib.pyplot as plt
import mpl_toolkits.mplot3d.art3d as art3d
from matplotlib.animation import FuncAnimation
from matplotlib.patches import Circle

# 为两个对象创建虚拟数据
lon = np.sort(277.0 + np.random.rand(2,100)*2)
lat = np.sort(48 + np.random.rand(2,100))
Z  = np.sort(20000 + np.random.rand(2,100)*8000)
lat[1] -= 2*(-lat[1][0] + lat[1]) # 将线条移动到不同的方向

这是用于静态图表的代码。

# 创建主图并设置边界(根据需要更改这些值)
fig = plt.figure(6)
ax = fig.add_subplot(111, projection='3d')
ax.set_xlim(276, 280)
ax.set_ylim(46, 50)
ax.set_zlim(np.min(Z), 30000)

ax.set_xlabel('经度 [Deg]')
ax.set_ylabel('纬度 [Deg]')
ax.set_zlabel('高度 [Km]')
ax.zaxis.set_pane_color((0.36, 0.7, 0.42, 0.75)) # 设置“地面”为绿色

# 绘制对象1的数据
# 绘制对象路径的线条
line = ax.plot(lon[0], lat[0], Z[0], c='k')
# 绘制从地面到对象最终位置的垂直线
vertLine = ax.plot([lon[0][-1], lon[0][-1]], [lat[0][-1], lat[0][-1]], [np.min(Z), Z[0][-1]], c='k')
# 在对象的最终位置绘制一个点
dot = ax.plot(lon[0][-1], lat[0][-1], Z[0][-1], linestyle="", marker="o", c='k')

# 绘制对象2的数据(详情请参阅上文)
line1 = ax.plot(lon[1], lat[1], Z[1], c='r', alpha=1)
vertLine1 = ax.plot([lon[1][-1], lon[1][-1]], [lat[1][-1], lat[1][-1]], [np.min(Z), Z[1][-1]], c='r', alpha=1)
dot1 = ax.plot(lon[1][-1], lat[1][-1], Z[1][-1], linestyle="", marker="o", c='r', alpha=1)

# 在“地面”上添加绿色参考圆
p = Circle((278, 48.5), 1, alpha=0.75, edgecolor=(0.3, 0.6, 0.39, 0.75), fill=False)
ax.add_patch(p)
art3d.pathpatch_2d_to_3d(p, z=np.min(Z), zdir="z")
ax.text(278, 48.5, np.min(Z), "x", color=(0.3, 0.6, 0.39, 0.75))

# 创建一个新的子图以查看从顶部向下的视图
ax2 = fig.add_subplot(331)
ax2.set_xlim(276, 280)
ax2.set_ylim(46, 50)
ax2.set_aspect('equal')

# 添加参考圆和背景颜色
ax2.set_facecolor((0.36, 0.7, 0.42, 0.75))
p2 = Circle((278, 48.5), 1, alpha=0.75, facecolor=(0.3, 0.6, 0.39, 0.75))
ax2.add_patch(p2)

# 绘制路径线和最终位置点
ax2.plot(lon[0], lat[0], c='k')
ax2.plot(lon[1], lat[1], c='r')
ax2.scatter(lon[0][-1], lat[0][-1], c='k', s=20)
ax2.scatter(lon[1][-1], lat[1][-1], c='r', s=20)

# 显示图表!
plt.show()

这是创建图表随时间变化的动画版本的代码。

# 创建带有适当参数的图/轴
fig = plt.figure(6)
ax = fig.add_subplot(111, projection='3d')
ax.set_xlim(276, 280)
ax.set_ylim(47, 50)
ax.set_zlim(18000, 30000)

ax.set_xlabel('经度 [Deg]')
ax.set_ylabel('纬度 [Deg]')
ax.set_zlabel('高度 [Km]')
ax.zaxis.set_pane_color((0.36, 0.7, 0.42, 0.75))

# 创建第一个对象的所有组件
line, = ax.plot(lon[0][:2], lat[0][:2], Z[0][:2], c='k', alpha=1)
vertLine, = ax.plot([lon[0][1], lon[0][1]], [lat[0][1], lat[0][1]], [np.min(Z[0]), Z[0][1]], c='k', alpha=1)
dot, = ax.plot(lon[0][1], lat[0][1], Z[0][1], linestyle="", marker="o", c='k', alpha=1)

# 创建第二个对象的所有组件
line1, = ax.plot(lon[1][:2], lat[1][:2], Z[1][:2], c='r', alpha=1)
vertLine1, = ax.plot([lon[1][1], lon[1][1]], [lat[1][1], lat[1][1]],

<details>
<summary>英文:</summary>

This answer shows how to create the final plot that you asked for. Both requests (single color and connected line) are very possible. A Google search of your desired plot image shows that it was originally an `animation`, which is something else that I have included.

### Answer ###
Use `ax.plot(...)` instead of `ax.scatter(...)` in order to connect the points with a line. Then you can add a few other features to make the output look more like your end goal.

### Example Output ###
Here is a figure showing your end goal. The code to reproduce the figure is added below.

[![static version of the hodograph][1]][1]

It is also possible to create an animation of the plot over time. Note that the color of the lines changes as the distance from the start position increases. This feature is easily disabled.

[![animated hodograph][2]][2]

### Code ###
This is some setup code to be used for both static and animated figures.

necessary imports

import numpy as np
import matplotlib.pyplot as plt
import mpl_toolkits.mplot3d.art3d as art3d
from matplotlib.animation import FuncAnimation
from matplotlib.patches import Circle

creating dummy data for two objects

lon = np.sort(277.0 + np.random.rand(2,100)*2)
lat = np.sort(48 + np.random.rand(2,100))
Z = np.sort(20000 + np.random.rand(2,100)8000)
lat1 -= 2
(-lat[1][0] + lat1) # moving the lines in different directions


This is for the static version of the figure.

creating the main figure and setting boundaries (change these as needed)

fig = plt.figure(6)
ax = fig.add_subplot(111, projection='3d')
ax.set_xlim(276, 280)
ax.set_ylim(46, 50)
ax.set_zlim(np.min(Z), 30000)

ax.set_xlabel('longitude [Deg]')
ax.set_ylabel('latitude [Deg]')
ax.set_zlabel('Altitude [Km]')
ax.zaxis.set_pane_color((0.36, 0.7, 0.42, 0.75)) # making the 'ground' green

plotting data from object 1

line plot for the path of the object

line = ax.plot(lon[0],lat[0],Z[0], c='k')

plotting a vertical line from the ground to the final position of the object

vertLine = ax.plot([lon[0][-1],lon[0][-1]],[lat[0][-1],lat[0][-1]],[np.min(Z),Z[0][-1]], c='k')

plotting a dot at the final postion of the object

dot = ax.plot(lon[0][-1], lat[0][-1], Z[0][-1], linestyle="", marker="o", c='k')

plotting data from object 2 (see above for details)

line1 = ax.plot(lon1,lat1,Z1, c='r', alpha=1)
vertLine1 = ax.plot([lon[1][-1],lon[1][-1]],[lat[1][-1],lat[1][-1]],[np.min(Z),Z[1][-1]], c='r', alpha=1)
dot1 = ax.plot(lon[1][-1], lat[1][-1], Z[1][-1], linestyle="", marker="o", c='r', alpha=1)

adding green reference circle to the 'ground'

p = Circle((278,48.5),1, alpha=0.75, edgecolor=(0.3, 0.6, 0.39, 0.75), fill=False)
ax.add_patch(p)
art3d.pathpatch_2d_to_3d(p, z=np.min(Z), zdir="z")
ax.text(278,48.5,np.min(Z),"x", color=(0.3, 0.6, 0.39, 0.75))

creating a new subplot for top down view

ax2 = fig.add_subplot(331)
ax2.set_xlim(276, 280)
ax2.set_ylim(46, 50)
ax2.set_aspect('equal')

adding reference circle and background color

ax2.set_facecolor((0.36, 0.7, 0.42, 0.75))
p2 = Circle((278,48.5),1, alpha=0.75, facecolor=(0.3, 0.6, 0.39, 0.75))
ax2.add_patch(p2)

plotting path lines and final position dots

ax2.plot(lon[0],lat[0], c='k')
ax2.plot(lon1,lat1, c='r')
ax2.scatter(lon[0][-1], lat[0][-1], c='k',s=20)
ax2.scatter(lon[1][-1], lat[1][-1], c='r',s=20)

Show the plot!

plt.show()


This is the code to create an animated version of the plot over time.

create figure/axis with appropriate params

fig = plt.figure(6)
ax = fig.add_subplot(111, projection='3d')
ax.set_xlim(276, 280)
ax.set_ylim(47, 50)
ax.set_zlim(18000, 30000)

ax.set_xlabel('longitude [Deg]')
ax.set_ylabel('latitude [Deg]')
ax.set_zlabel('Altitude [Km]')
ax.zaxis.set_pane_color((0.36, 0.7, 0.42, 0.75))

create all components of the first object

line, = ax.plot(lon[0][:2],lat[0][:2],Z[0][:2], c='k', alpha=1)
vertLine, = ax.plot([lon0,lon0],[lat0,lat0],[np.min(Z[0]),Z0], c='k', alpha=1)
dot, = ax.plot(lon0, lat0, Z0, linestyle="", marker="o", c='k', alpha=1)

create all components of the second object

line1, = ax.plot(lon[1][:2],lat[1][:2],Z[1][:2], c='r', alpha=1)
vertLine1, = ax.plot([lon1,lon1],[lat1,lat1],[np.min(Z1),Z1], c='r', alpha=1)
dot1, = ax.plot(lon1, lat1, Z1, linestyle="", marker="o", c='r', alpha=1)

def animate(i, colUpdate, numFrs): # colUpdate (bool), numFrs (int)
# update the data for the path lines
line.set_data(lon[0][:(i+1)*2],lat[0][:(i+1)*2])
line.set_3d_properties(Z[0][:(i+1)*2])
line1.set_data(lon[1][:(i+1)*2],lat[1][:(i+1)*2])
line1.set_3d_properties(Z[1][:(i+1)*2])

# update the data for the vertical lines
vertLine.set_data(np.array([lon[0][((i+1)*2)-1],lon[0][((i+1)*2)-1]]),np.array([lat[0][((i+1)*2)-1],lat[0][((i+1)*2)-1]]))
vertLine.set_3d_properties([np.min(Z[0]),Z[0][((i+1)*2)-1]])
vertLine1.set_data(np.array([lon[1][((i+1)*2)-1],lon[1][((i+1)*2)-1]]),np.array([lat[1][((i+1)*2)-1],lat[1][((i+1)*2)-1]]))
vertLine1.set_3d_properties([np.min(Z[1]),Z[1][((i+1)*2)-1]])
# update the data for the endpoint dots
dot.set_data(lon[0][((i+1)*2)-1],lat[0][((i+1)*2)-1])
dot.set_3d_properties(Z[0][((i+1)*2)-1])
dot1.set_data(lon[1][((i+1)*2)-1],lat[1][((i+1)*2)-1])
dot1.set_3d_properties(Z[1][((i+1)*2)-1])
# update the colors, if necessary
if colUpdate:
co = np.array([(i/numFrs),0.0,0.0])
co1 = np.array([0.0,0.0,(i/numFrs)])
line.set_color(co)
vertLine.set_color(co)
dot.set_color(co)
line1.set_color(co1)
vertLine1.set_color(co1)
dot1.set_color(co1)
# return all updated objects
return line, vertLine, dot, line1, vertLine1, dot1,

set params and create the animation artist

updateCol = True
numFrames = int(len(Z[0]) /2)
anim = FuncAnimation(fig, animate, frames = numFrames,interval = 100, fargs=(updateCol,numFrames,), blit=False, repeat=False)

Show the plot!

plt.show()


### Edit ###
In order to fix the animation portion of the code to be compatible with Matplotlib 3.5.1, you must change the following section of code in the `animate(...)` function. Replace the following:
# update the data for the endpoint dots
dot.set_data(lon[0][((i+1)*2)-1],lat[0][((i+1)*2)-1])
dot.set_3d_properties(Z[0][((i+1)*2)-1])
dot1.set_data(lon[1][((i+1)*2)-1],lat[1][((i+1)*2)-1])
dot1.set_3d_properties(Z[1][((i+1)*2)-1])

With:
# update the data for the endpoint dots
dot.set_data(lon[0][((i+1)*2)-1],lat[0][((i+1)*2)-1])
dot.set_3d_properties([Z[0][((i+1)*2)-1]])
dot1.set_data(lon[1][((i+1)*2)-1],lat[1][((i+1)*2)-1])
dot1.set_3d_properties([Z[1][((i+1)*2)-1]])

All this does is change the input for the `set_3d_properties(...)` to list format, which is the new standard in Matplotlib 3.5.1. See this [open issue][3] for a description of the problem.
Does this help?
[1]: https://i.stack.imgur.com/cWxum.png
[2]: https://i.stack.imgur.com/qEK94.gif
[3]: https://github.com/matplotlib/matplotlib/issues/22308
</details>

huangapple
  • 本文由 发表于 2023年6月2日 02:17:03
  • 转载请务必保留本文链接:https://go.coder-hub.com/76384660.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定