【发布时间】:2020-11-22 17:21:26
【问题描述】:
我在“x-cord”、“y-cord”、“value”列下有包含点的文件。这些是不规则间隔的。我正在尝试制作“价值”的等高线图并将其覆盖在原始域上。我放弃了在 pgfplots 和 matlab 中尝试这样做,并认为我会给 python 一个机会。任何这些脚本中的答案都可以。 python脚本如下
import numpy as np
from scipy.interpolate import griddata
import matplotlib.pyplot as plt
import numpy.ma as ma
from numpy.random import uniform, seed
from scipy.spatial import ConvexHull
#
# Loading data
filename = "strain.dat"
coordinates = []
x_c = []
y_c = []
z_c = []
xyz = open(filename)
title = xyz.readline()
for line in xyz:
x,y,z = line.split()
coordinates.append([float(x), float(y), float(z)])
x_c.append([float(x)])
y_c.append([float(y)])
z_c.append([float(z)])
xyz.close()
#
# Rehaping and translating data
x_c=np.ravel(np.array(x_c))
y_c=np.ravel(np.array(y_c))
z_c=np.ravel(np.array(z_c))
x_c = x_c-100.0
y_c = y_c-100.0
#
# Checking the convex hull
points=np.column_stack((x_c,y_c))
hull = ConvexHull(points);
plt.plot(points[hull.vertices,0], points[hull.vertices,1], 'r--', lw=2)
plt.scatter(x_c, y_c, marker='o', s=5, zorder=10)
#
# Mapping the irregular data onto a regular grid and plotting
xic = np.linspace(min(x_c), max(x_c), 1000)
yic = np.linspace(min(y_c), max(y_c), 1000)
zic = griddata((x_c, y_c), z_c, (xic[None,:], yic[:,None]))
CS = plt.contour(xic,yic,zic,15,linewidths=0.5,colors='k')
CS = plt.contourf(xic,yic,zic,15,cmap=plt.cm.summer)
plt.colorbar() # draw colorbar
#
#plt.scatter(x_c, y_c, marker='o', s=5, zorder=10)
plt.axis('equal')
plt.savefig('foo.pdf', bbox_inches='tight')
plt.show()
输出看起来像
问题是griddata使用了一个凸包,而这个凸包超出了不规则数据的边缘。有什么办法可以将原始点边界边缘之外的griddata点的值设置为零?
编辑
最后我认输了,回到了 Matlab。我必须将数据导出到 pgfplots 以获得漂亮的图。我想出的代码是
x = strain.x;
y = strain.y;
z = strain.eps;
% Get the alpha shape (couldn't do this in python easily)
shp = alphaShape(x,y,.001);
% Get the boundary nodes
[bi, xy] = boundaryFacets(shp);
no_grid = 500;
xb=xy(:,1);
yb=xy(:,2);
[X,Y] = ndgrid(linspace(min(x),max(x),no_grid),linspace(min(y),max(y),no_grid));
Z = griddata(x,y,z,X,Y,'v4');
% Got through the regular grid and set the values which are outside the boundary of the original domain to Nans
for j = 1:no_grid
[in,on] = inpolygon(X(:,j),Y(:,j),xb,yb);
Z(~in,j) = NaN;
end
contourf(X,Y,Z,10),axis equal
colorbar
hold on
plot(xb,yb)
axis equal
hold off
如果有人可以在 Python 中做类似的事情,我会很乐意接受答案。
【问题讨论】:
-
对于一个漂亮的梯形,每个 行 有两个点 - 一个最小值和一个最大值;您可以将 griddata 中的点与边界 by row 进行比较,并确定它们是在 (True) 还是在 (False) 之间 - 创建一个布尔掩码,然后将 griddata 乘以掩码。
-
这是个好主意,它有点超出了我的 python 能力,虽然不规则点不在漂亮的规则行上。
-
为了有人给你解决方案,你需要提供问题的minimal reproducible example。 @wwii 的评论原则上是正确的,所以这完全取决于数据看起来是否容易。
标签: python matplotlib contour edge-detection