曲线由两个散乱点面之间的交点定义,采样方式不同

时间:2017-07-11 20:22:17

标签: python matplotlib scipy interpolation

我有两组1__scatter_xyz.dat2__scatter_xyz.dat分散点。

这些点由3个坐标定义:xyz

1__scatter_xyz.dathttps://paste.ubuntu.com/25069931/

2__scatter_xyz.dathttps://paste.ubuntu.com/25069938/

这两组散点在一个区域相交:

gnuplot>  splot "1__scatter_xyz.dat" using 3:1:2 with points lt 1 title "1", "2__scatter_xyz.dat" using 3:1:2 with points lt 1 lc 2 title "2"

gnuplot> set xlabel 'x'
gnuplot> set ylabel 'y'
gnuplot> set zlabel 'z'

enter image description here

set 1表面与set 2表面之间的交叉将定义一条线/曲线,在2D y - x图表中绘制,将给出我们这两组之间的相界。

我想在2D y - x图中绘制这条线/曲线,这是由两个曲面的交叉产生的。

我如何解决此问题的方式:

我们可以定义一个新函数w = z_{1} - z_{2}。 这两个表面之间的交叉将是w = (z_{1} - z_{2}) = 0的点。 然后我可以定义两个区域:

a)w = 0

的区域

b)w \neq 0

的区域

如果我在2D w - y图表中绘制x的这两个值:

enter image description here

然后我可以定义这条线/曲线是这两组之间的相界:

a)w = 0两个集合共存的区域

b)w \neq 0所在的区域,两组不共存

为什么我无法使用此解决方案:

如果我们只删除.dat文件上的空白行并排序x - 明智:

sed '/^\s*$/d' 1__scatter_xyz.dat | grep -v "^#" | sort -k1 -n > 1__scatter_xyz_sort_x_wise.dat

sed '/^\s*$/d' 2__scatter_xyz.dat | grep -v "^#" | sort -k1 -n > 2__scatter_xyz_sort_x_wise.dat

如果查看两个x_wise.dat文件,则会有重叠数据: set 1y -4.41变为10.85,set 2从8.06变为17.64。 y的数组在两个集合上都不同。但是,x的数组是相同的:从10到2000,步长为20.1。

因此,集合1和集合2具有相同的x_{j}数组:在20.1的步骤中从10到2000。 但是,两个集合都没有y s的相同数组:y_{i}^{1}有一个数组set 1y_{i}^{2}有一个数组set 2

换句话说,

enter image description here

因此,想象一下,我发现两个表面都具有相同的z值。 此点将由x_{j}y_{i}^{1}y_{i}^{2}定义,而不是两个唯一坐标。

更有效的想法非常受欢迎。

使用scipy's griddata

import numpy as np
import sys
import matplotlib.pyplot as plt
from scipy.interpolate import griddata

# Load data:
x_1, y_1, z_1 = = np.loadtxt(./1__scatter_xyz.dat, skiprows = 1).T
x_2, y_2, z_2 = = np.loadtxt(./2__scatter_xyz.dat, skiprows = 1).T

# According to the example posted in the above scipy's griddata link,
# variables "points" and "values" are defined, so we can similarly use:    
points_1 = (x_1, y_1)
points_2 = (x_2, y_2)
values_1 = (z_1)
values_2 = (z_2)

我们现在必须定义网格。 正如帖子中深入解释的那样,y数组在两个集合上的采样方式不同。

我们仔细研究数据,y空间的两个集合之间存在重叠区域:

enter image description here

因此,继续this scipy's griddata example,我们可以设置:

T_initial = 10.0
T_end = 2000.0
number_of_Ts = 100

P_initial = 8.0622
P_end = 10.8535
number_of_Ps = 100

# And then define the mesh as:    
grid_T, grid_P = np.meshgrid(np.linspace(T_initial, T_end, number_of_Ts), np.linspace(P_initial, P_end, number_of_Ps))

此时我不知道如何继续,因为我们实际上只能定义两组网格?

grid_Gibbs_solid_1 = griddata(points_solid_1, values_solid_1, (grid_T, grid_P), method='cubic')    
grid_Gibbs_solid_2 = griddata(points_solid_2, values_solid_2, (grid_T, grid_P), method='cubic')

要采用哪种方法?

1 个答案:

答案 0 :(得分:2)

f(x,y)g(x,y)表示与您的两个曲面相对应的函数。您要寻找的是绘制与等式f(x,y) == g(x,y)对应的轮廓,或等效f(x,y) - g(x,y) == 0

Matplotlib为此提供了函数contour。举个简单的例子,考虑函数给出的两个表面

import numpy as np    

def f(x, y):
    return np.exp(-(x**2 + y**2))

def g(x, y):
    return (3*x**2 + y**2)/16

以下代码段绘制了函数f-g,与f-g==0对应的(3D)轮廓以及z平面上的(2D)投影

from mpl_toolkits.mplot3d import Axes3D
from matplotlib import cm

fig = plt.figure(figsize = (8,8))
ax = fig.gca(projection='3d')
X = np.linspace(-2, 2, 30)
Y = np.linspace(-2, 2, 30)
X, Y = np.meshgrid(X, Y)

Z = g(X,Y)

ax.plot_surface(X, Y, f(X,Y)-g(X,Y), rstride=1, cstride=1, cmap = cm.viridis, antialiased=False, alpha = 0.5)
ax.contour(X, Y, f(X,Y) - g(X,Y), zdir='z', offset=-2, levels = [0])
ax.contour(X, Y, f(X,Y) - g(X,Y), levels = [0])
ax.set_zlim(zmin = -2)

enter image description here

在您的情况下,您有数据样本而不是函数。您可以通过插值轻松地从数据中获取曲面的(近似)函数(参见scipy.interpolate)。