如何用pyqtgraph绘制地球轨道?

问题描述 投票:0回答:1

假设我有一组数据,由时间序列和X、Y、Z千点坐标组成(示例数据如下)。我想以 3D 方式绘制数据,就像地球绕太阳运行一样,或者地球绕太阳运行并带有 10 个褪色地球的轨迹。

通过遵循 3D 示例代码,目前我能够同时绘制所有点并进行淡入淡出。但我不知道如何迭代这些点并使用计时器正确启动/停止来更新绘图。

(轨道.csv)

TimeDiff,X,Y,Z
0.0,0.00,0.27,-8.28
0.04,-0.96,0.27,-11.46
0.17,-0.96,-0.18,-13.81
0.36,-2.69,-0.18,-16.34
0.5,-2.69,-0.77,-17.69
0.73,-4.82,-0.77,-19.20
0.83,-4.82,-0.99,-19.43
1.04,-6.10,-0.99,-19.68
1.18,-6.10,-0.84,-18.87
1.39,-4.20,-0.84,-17.49
1.5,-4.20,-0.65,-15.63
1.72,-2.09,-0.65,-13.38
1.83,-2.09,-0.31,-10.49
2.05,-0.92,-0.31,-7.47
2.18,-0.92,0.09,-4.10
2.36,-0.12,0.09,-0.58
2.52,-0.12,0.20,2.71
2.7,-0.05,0.20,6.11
2.86,-0.05,0.11,9.12
3.03,-0.89,0.11,12.30
3.18,-0.89,-0.29,14.46

或降价格式:

| Time     | X     | Y     | Z      |
| -------- | ----- | ----- | ------ |
| 0        | 0     | 0.27  | -8.28  |
| 0.04     | -0.96 | 0.27  | -11.46 |
| 0.17     | -0.96 | -0.18 | -13.81 |
| 0.36     | -2.69 | -0.18 | -16.34 |
| 0.5      | -2.69 | -0.77 | -17.69 |
| 0.73     | -4.82 | -0.77 | -19.2  |
| 0.83     | -4.82 | -0.99 | -19.43 |
| 1.04     | -6.1  | -0.99 | -19.68 |
| 1.18     | -6.1  | -0.84 | -18.87 |
| 1.39     | -4.2  | -0.84 | -17.49 |
| 1.5      | -4.2  | -0.65 | -15.63 |
| 1.72     | -2.09 | -0.65 | -13.38 |
| 1.83     | -2.09 | -0.31 | -10.49 |
| 2.05     | -0.92 | -0.31 | -7.47  |
| 2.18     | -0.92 | 0.09  | -4.1   |
| 2.36     | -0.12 | 0.09  | -0.58  |
| 2.52     | -0.12 | 0.2   | 2.71   |

from pyqtgraph.Qt import QtCore, QtGui, QtWidgets
import pyqtgraph.opengl as gl
from pyqtgraph import functions as fn
import numpy as np
import pandas as pd
import os


app = QtWidgets.QApplication([])
w = gl.GLViewWidget()
w.opts['distance'] = 500
w.show()
w.setWindowTitle('pyqtgraph example: GLVolumeItem')

ax = gl.GLAxisItem()
ax.setSize(900, 900, 900)
w.addItem(ax)

f = "Orbit.csv"
df = pd.read_csv(f)
timeList = df['TimeDiff'].tolist()
comp_x = df["X"].tolist()
comp_y = df["Y"].tolist()
comp_z = df["Z"].tolist()

w.setWindowTitle('pyqtgraph example: DateAxisItem')

speed = 1
measureTimeList = [x / speed for x in timeList]

line_x = [x for x in comp_x]
line_y = [x for x in comp_y]
line_z = [x for x in comp_z]

pos = np.empty((len(line_x), 3))
size = np.empty(len(line_x))
color = np.empty((len(line_x), 4))

pos[2] = (0, 0, 1);
size[2] = 1. / 1.0;
color[2] = (0.0, 1.0, 0.0, 1)


def update(): ## update volume colors
    global phase, sp2, d2
    s = -np.cos(d2*2+phase)
    color = np.empty((len(line_x), 4), dtype=np.float32)
    color[:, 3] = fn.clip_array(s * 0.1, 0., 1.)
    color[:, 0] = fn.clip_array(s * 3.0, 0., 1.)
    color[:, 1] = fn.clip_array(s * 1.0, 0., 1.)
    color[:, 2] = fn.clip_array(s ** 3, 0., 1.)
    sp2.setData(color=color)
    phase -= 0.1

t = QtCore.QTimer()
t.timeout.connect(update)
t.start(20)


color = np.ones((pos.shape[0], 4))
for i in range(len(line_x)):
    pos[i] = (line_z[i], line_x[i], line_y[i])

d2 = 2
phase = 90.
size = 2
s = -np.cos(d2 * 2 + phase)
color[:, 3] = fn.clip_array(s * 0.1, 0., 1.)
color[:, 0] = fn.clip_array(s * 3.0, 0., 1.)
color[:, 1] = fn.clip_array(s * 1.0, 0., 1.)
color[:, 2] = fn.clip_array(s ** 3, 0., 1.)
sp2 = gl.GLScatterPlotItem(pos=pos, color=(1, 1, 1, 1), size=size)
w.addItem(sp2)


## Start Qt event loop unless running in interactive mode.
if __name__ == '__main__':
    import sys

    if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
        QtWidgets.QApplication.instance().exec_()
python pyqtgraph
1个回答
0
投票

不幸的是,我在您的数据中没有看到轨道。尽管如此,这是我的方法:

将所有颜色设置为完全透明。然后创建一个从 0 到 1 的“透明度渐变”,并让这个渐变“滚动”到每次更新的位置上。这样,它看起来就像一个移动的褪色物体:

from pyqtgraph.Qt import QtCore, QtWidgets
import pyqtgraph.opengl as gl
import numpy as np
import pandas as pd


app = QtWidgets.QApplication([])
w = gl.GLViewWidget()
w.opts["distance"] = 100
w.show()

ax = gl.GLAxisItem()
ax.setSize(900, 900, 900)
w.addItem(ax)

df = pd.read_csv("Orbit.csv")

frame_count = 0


def update():
    global frame_count, sp2
    # create transparency ramp over n_display positions
    n_display = 6
    color = np.ones((sp2.pos.shape[0], 4), dtype=np.float32)
    color[:, 3] = 0
    color[: n_display + 1, 3] = np.linspace(0, 1, n_display + 1)
    # move the ramp over the array with increasing frame_count
    color = np.roll(color, frame_count, axis=0)
    frame_count += 1
    sp2.setData(color=color)


t = QtCore.QTimer()
t.timeout.connect(update)
t.start(100)

pos = [(z, x, y) for z, x, y in zip(df["Z"], df["X"], df["Y"])]

sp2 = gl.GLScatterPlotItem(pos=pos, color=(1, 1, 1, 1), size=5)
w.addItem(sp2)

if __name__ == "__main__":
    import sys

    if (sys.flags.interactive != 1) or not hasattr(QtCore, "PYQT_VERSION"):
        QtWidgets.QApplication.instance().exec()
© www.soinside.com 2019 - 2024. All rights reserved.