查看非结构化数据集的3D场线

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

Viewing 3d Field Lines of an unstructured dataset

问题

我尝试查看一个不完整的常规网格矢量场的场线,首先使用pyVista Streamlines,然后使用plotly,但没有成功...我在其他2D流场图中取得了好的结果:

数据的2D流场图

有人可以帮助我吗?我找不到答案...这是我的数据:https://wetransfer.com/downloads/7f3c4ae01e5922e753ea708134f956e720230214141330/bf11ab

import pandas as pd
import numpy as np
import pyvista as pv
import plotly.graph_objects as go

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

X = df['X']
Y = df['Y']
Z = df['Z']
Vx = df['Vx']
Vy = df['Vy']
Vz = df['Vz']

fig = go.Figure(data=go.Streamtube(
    x = X,
    y = Y,
    z = Z,
    u = Vx,
    v = Vy,
    w = Vz,
    starts = dict(
        x = X.sample(frac=0.01,replace=False),
        y = Y.sample(frac=0.01,replace=False),
        z = Z.sample(frac=0.01,replace=False)
    ),
    sizeref = 1,
    colorscale = 'Portland',
    showscale = False,
    maxdisplayed = 30000000
))

fig.update_layout(
    scene = dict(
        aspectratio = dict(
            x = 1,
            y = 1,
            z = 1
        )
    ),
    margin = dict(
        t = 10,
        b = 10,
        l = 10,
        r = 10
    )
)

fig.show(renderer="browser")

# Streamlines

mix_FD_grid = np.load("C:/Users/hd377/OneDrive - ensam.eu/0-Thesis/Fibres_Direction_in_allvolume/mix/mix_FD_grid.npy")

origin = (0,0,0)
mesh = pv.UniformGrid(dimensions=mix_FD_grid[:,:,:,0].shape, spacing=(1, 1, 1), origin=origin)
vectors = np.empty((mesh.n_points, 3))
vectors[:, 0] = mix_FD_grid[:,:,:,0].flatten()
vectors[:, 1] = mix_FD_grid[:,:,:,1].flatten()
vectors[:, 2] = mix_FD_grid[:,:,:,2].flatten()

mesh['vectors'] = vectors

stream, src = mesh.streamlines(
    'vectors', return_source=True, max_steps=20000, n_points=200, source_radius=25, source_center=(15, 0, 30)
)

p = pv.Plotter()
p.add_mesh(mesh.outline(), color="k")
p.add_mesh(stream.tube(radius=0.1))
p.camera_position = [(182.0, 177.0, 50), (139, 105, 19), (-0.2, -0.2, 1)]
p.show()

在我的浏览器中,plotly窗口确实出现了,但根本看不到任何管道,坐标轴的值也是错误的。pyVista确实显示了一些内容,但方向错误,显然不是预期的(环绕中央锥形的纵向流)。

英文:

I have tried to view field lines of an uncomplete regular grid vector field with first pyVista Streamlines and then with plotly without success... I have yet good results with other 2d streamplots :

2d streamplot of the data

Could someone help me with this ? I found no answer... Here is my data : https://wetransfer.com/downloads/7f3c4ae01e5922e753ea708134f956e720230214141330/bf11ab

import pandas as pd
import numpy as np
import pyvista as pv
import plotly.graph_objects as go
df = pd.read_csv("mix_griddata.csv")
X = df['X']
Y = df['Y']
Z = df['Z']
Vx = df['Vx']
Vy = df['Vy']
Vz = df['Vz']
fig = go.Figure(data=go.Streamtube(
x = X,
y = Y,
z = Z,
u = Vx,
v = Vy,
w = Vz,
starts = dict(
x = X.sample(frac=0.01,replace=False),
y = Y.sample(frac=0.01,replace=False),
z = Z.sample(frac=0.01,replace=False)
),
sizeref =1,
colorscale = 'Portland',
showscale = False,
maxdisplayed = 30000000
))
fig.update_layout(
scene = dict(
aspectratio = dict(
x = 1,
y = 1,
z = 1
)
),
margin = dict(
t = 10,
b = 10,
l = 10,
r = 10
)
)
fig.show(renderer="browser")
#Streamlines
mix_FD_grid = np.load("C:/Users/hd377/OneDrive - ensam.eu/0-Thesis/Fibres_Direction_in_allvolume/mix/mix_FD_grid.npy")
origin = (0,0,0)
mesh = pv.UniformGrid(dimensions=mix_FD_grid[:,:,:,0].shape, spacing=(1, 1, 1), origin=origin)
vectors = np.empty((mesh.n_points, 3))
vectors[:, 0] = mix_FD_grid[:,:,:,0].flatten()
vectors[:, 1] = mix_FD_grid[:,:,:,1].flatten()
vectors[:, 2] = mix_FD_grid[:,:,:,2].flatten()
mesh['vectors'] = vectors
stream, src = mesh.streamlines(
'vectors', return_source=True, max_steps = 20000, n_points=200, source_radius=25, source_center=(15, 0, 30)
)
p = pv.Plotter()
p.add_mesh(mesh.outline(), color="k")
p.add_mesh(stream.tube(radius=0.1))
p.camera_position = [(182.0, 177.0, 50), (139, 105, 19), (-0.2, -0.2, 1)]
p.show() 

The plotly window does appear in my browser but no tube are visible at all, and the axes values are false.
The pyVista does show something, but in the wrong direction, and clearly not what expected (longitudinal flux circumventing a central cone).

答案1

得分: 1

  1. 我只会处理PyVista。很难确定,我只是猜测,但你的数据可能按错误顺序排列。

  2. 首先,你的数据本身不一致:你的CSV有1274117行,而你的多维数组的形状是(37, 364, 100, 3),总共有1346800个向量。而你的问题标题说"无结构",但你的PyVista尝试使用了一个均匀的网格。

  3. 其次,你的CSV实际上并不对应于一个规则的网格,例如,在文件末尾,你有以368.693,36.971999999999994开头的15行,然后以369.71999999999997,36.971999999999994开头的8行,然后以370.74699999999996,36.971999999999994开头的一行。在规则网格中,每个块中的项目数量应该是相同的。

  4. 第三,你的CSV具有不寻常(类似MATLAB)的布局,轴的顺序是z-x-y(而不是x-y-z或z-y-x)。这是一个强烈的线索,表明你的数据由于内存布局问题而被损坏。但前两点意味着我不能验证你的4D数组是如何创建的,我必须认为它是正确的。

仅绘制原始数据可以明显看出,数据在你的原始版本中被损坏了(带有一些样式清理)。

碎片化的图案是由于错误的内存布局导致的。

如果我们假设布局大致合理,尝试使用列主要布局("F"代表"Fortran",也被MATLAB使用)似乎更有道理:

这里有一些具有一些大尺度特征的合理看起来的颜色图案的延长盒子。

因此,我们可以尝试使用这个来进行流线绘制:

它看起来不太好:

所以,你说流线应该是纵向的,但在这里它们明显是横向的。是不是x和y字段组件被交换了?我不能确定,所以让我们试试吧!

现在我们正在谈论!

额外的:在体积图上的y字段组件:

带有箱子中央的龙卷风形状明亮漏斗的半透明体积图。

英文:

I'll only be tackling PyVista. It's hard to say for sure and I'm only guessing, but your data is probably laid out in the wrong order.

  1. For starters, your data is inconsistent to begin with: your CSV has 1274117 rows whereas your multidimensional array has shape (37, 364, 100, 3), for a total of 1346800 vectors. And your question title says "unstructured", but your PyVista attempt uses a uniform grid with.
  2. Secondly, your CSV doesn't correspond to a regular grid in the first place, e.g. at the end of the file you have 15 rows starting with 368.693,36.971999999999994, then 8 rows starting with 369.71999999999997,36.971999999999994, then a single row starting with 370.74699999999996,36.971999999999994. In a regular grid you'd get the same number of items in each block.
  3. Thirdly, your CSV has an unusual (MATLAB-smelling) layout that the order of axes is z-x-y (rather than either x-y-z or z-y-x). This is a strong clue that your data is mangled due to memory layout issues when flattened. But the previous two point mean that I can't verify how your 4d array was created, I have to take it for granted that it's correct.

Just plotting your raw data makes it obvious that the data is mangled in your original version (with some style cleanup):

import numpy as np
import pyvista as pv

mix_FD_grid = np.load("mix_FD_grid.npy")

origin = (0, 0, 0)
mesh = pv.UniformGrid(dimensions=mix_FD_grid.shape[:-1], spacing=(1, 1, 1), origin=origin)
vectors = np.empty_like(mesh.points)
vectors[:, 0] = mix_FD_grid[..., 0].ravel()
vectors[:, 1] = mix_FD_grid[..., 1].ravel()
vectors[:, 2] = mix_FD_grid[..., 2].ravel()
mesh.point_data['vectors'] = vectors

mesh.plot()

查看非结构化数据集的3D场线

The fragmented pattern you can see is a hallmark of data mangling due to mistaken memory layout.

If we assume the layout is more or less sane, trying column-major layout ("F" for "Fortran", also used by MATLAB) seems to make a lot more sense:

vectors[:, 0] = mix_FD_grid[..., 0].ravel('F')
vectors[:, 1] = mix_FD_grid[..., 1].ravel('F')
vectors[:, 2] = mix_FD_grid[..., 2].ravel('F')
mesh.point_data['vectors'] = vectors

mesh.plot()

查看非结构化数据集的3D场线

So we can try using streamlines using that:

stream, src = mesh.streamlines(
    'vectors', return_source=True, max_steps=20000, n_points=200, source_radius=25, source_center=(15, 0, 30)
)

p = pv.Plotter()
p.add_mesh(mesh.outline(), color="k")
p.add_mesh(stream.tube(radius=0.1))
p.show()

It doesn't look great:
查看非结构化数据集的3D场线

So, you said that the streamlines should be longitudinal, but here they are clearly transversal. Can it be that the x and y field components are swapped? I can't tell, so let's try!

import numpy as np
import pyvista as pv

mix_FD_grid = np.load("mix_FD_grid.npy")

origin = (0, 0, 0)
mesh = pv.UniformGrid(dimensions=mix_FD_grid.shape[:-1], spacing=(1, 1, 1), origin=origin)
vectors = np.empty_like(mesh.points)
vectors[:, 0] = mix_FD_grid[..., 1].ravel('F')  # swap 0 <-> 1
vectors[:, 1] = mix_FD_grid[..., 0].ravel('F')  # swap 0 <-> 1
vectors[:, 2] = mix_FD_grid[..., 2].ravel('F')
mesh.point_data['vectors'] = vectors

stream, src = mesh.streamlines(
    'vectors', return_source=True, max_steps=20000, n_points=200, source_radius=25, source_center=(15, 0, 30)
)

p = pv.Plotter()
p.add_mesh(mesh.outline(), color="k")
p.add_mesh(stream.tube(radius=0.1))
p.show()

查看非结构化数据集的3D场线

Now we're talking!

Bonus: y field component on a volumetric plot:

mesh.plot(volume=True, scalars=vectors[:, 1], show_scalar_bar=False)

查看非结构化数据集的3D场线

huangapple
  • 本文由 发表于 2023年2月14日 22:23:42
  • 转载请务必保留本文链接:https://go.coder-hub.com/75449202.html
匿名

发表评论

匿名网友

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

确定