Python 不规则 XYZ 数据的轮廓/显示图
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/27004422/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Contour/imshow plot for irregular X Y Z data
提问by Scientist
I have data in X, Y, Z format where all are 1D arrays, and Z is the amplitude of the measurement at coordinate (X,Y). I'd like to show this data as a contour or 'imshow' plot where the contours/color represent the the value Z (amplitude).
我有 X、Y、Z 格式的数据,其中都是一维数组,Z 是坐标 (X,Y) 处的测量幅度。我想将此数据显示为等高线或“imshow”图,其中等高线/颜色表示值 Z(振幅)。
The grid for measurements and X and Y look are irregularly spaced.
用于测量和 X 和 Y 外观的网格是不规则间隔的。
Many thanks,
非常感谢,
len(X)=100
长度(X)=100
len(Y)=100
长度(Y)=100
len(Z)=100
长度(Z)=100
回答by Oliver W.
Does plt.tricontourf(x,y,z)satisfy your requirements?
是否plt.tricontourf(x,y,z)满足您的要求?
It will plot filled contours for irregularly spaced data (non-rectilinear grid).
它将为不规则间隔的数据(非直线网格)绘制填充轮廓。
You might also want to look into plt.tripcolor().
您可能还想查看plt.tripcolor().
import numpy as np
import matplotlib.pyplot as plt
x = np.random.rand(100)
y = np.random.rand(100)
z = np.sin(x)+np.cos(y)
f, ax = plt.subplots(1,2, sharex=True, sharey=True)
ax[0].tripcolor(x,y,z)
ax[1].tricontourf(x,y,z, 20) # choose 20 contour levels, just to show how good its interpolation is
ax[1].plot(x,y, 'ko ')
ax[0].plot(x,y, 'ko ')
plt.savefig('test.png')


回答by Adam Hughes
xx, yy = np.meshgrid(x, y)
plt.contour(xx, yy, z)
Doesn't matter if they are irregularly spaced, contour and 3d plots require a meshgrid.
它们是否间隔不规则无关紧要,轮廓和 3d 绘图需要网格。
回答by 8one6
(Source code @ the end...)
(源码@最后...)
Here's a little bit of eye candy that I produced playing around with this a bit. It explores the fact that a linear transformation of a meshgrid is still a meshgrid. I.e. on the left of all of my plots, I'm working with X and Y coordinates for a 2-d (input) function. On the right, I want to work with (AVG(X, Y), Y-X) coordinates for the same function.
这是我在玩这个的时候制作的一些眼睛糖果。它探讨了网格的线性变换仍然是网格的事实。即在我所有图的左侧,我正在处理二维(输入)函数的 X 和 Y 坐标。在右侧,我想使用 (AVG(X, Y), YX) 坐标来实现相同的功能。
I played around with making meshgrids in native coordinates and transforming them into meshgrids for the other coordinates. Works fine if the transform is linear.
我在本地坐标中制作网格并将它们转换为其他坐标的网格。如果变换是线性的,则工作正常。
For the bottom two graphs, I worked with random sampling to address your question directly.
对于底部的两个图表,我使用随机抽样直接解决您的问题。
Here are the images with setlims=False:

以下是图片setlims=False:

And the same with setlims=True:

和相同的setlims=True:

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
def f(x, y):
return y**2 - x**2
lim = 2
xlims = [-lim , lim]
ylims = [-lim, lim]
setlims = False
pde = 1
numpts = 50
numconts = 20
xs_even = np.linspace(*xlims, num=numpts)
ys_even = np.linspace(*ylims, num=numpts)
xs_rand = np.random.uniform(*xlims, size=numpts**2)
ys_rand = np.random.uniform(*ylims, size=numpts**2)
XS_even, YS_even = np.meshgrid(xs_even, ys_even)
levels = np.linspace(np.min(f(XS_even, YS_even)), np.max(f(XS_even, YS_even)), num=numconts)
cmap = sns.blend_palette([sns.xkcd_rgb['cerulean'], sns.xkcd_rgb['purple']], as_cmap=True)
fig, axes = plt.subplots(3, 2, figsize=(10, 15))
ax = axes[0, 0]
H = XS_even
V = YS_even
Z = f(XS_even, YS_even)
ax.contour(H, V, Z, levels, cmap=cmap)
ax.plot(H.flatten()[::pde], V.flatten()[::pde], linestyle='None', marker='.', color='.75', alpha=0.5, zorder=1, markersize=4)
if setlims:
ax.set_xlim([-lim/2., lim/2.])
ax.set_ylim([-lim/2., lim/2.])
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_title('Points on grid, contour')
ax = axes[1, 0]
H = H.flatten()
V = V.flatten()
Z = Z.flatten()
ax.tricontour(H, V, Z, levels, cmap=cmap)
ax.plot(H.flatten()[::pde], V.flatten()[::pde], linestyle='None', marker='.', color='.75', alpha=0.5, zorder=1, markersize=4)
if setlims:
ax.set_xlim([-lim/2., lim/2.])
ax.set_ylim([-lim/2., lim/2.])
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_title('Points on grid, tricontour')
ax = axes[0, 1]
H = (XS_even + YS_even) / 2.
V = YS_even - XS_even
Z = f(XS_even, YS_even)
ax.contour(H, V, Z, levels, cmap=cmap)
ax.plot(H.flatten()[::pde], V.flatten()[::pde], linestyle='None', marker='.', color='.75', alpha=0.5, zorder=1, markersize=4)
if setlims:
ax.set_xlim([-lim/2., lim/2.])
ax.set_ylim([-lim, lim])
ax.set_xlabel('AVG')
ax.set_ylabel('DIFF')
ax.set_title('Points on transformed grid, contour')
ax = axes[1, 1]
H = H.flatten()
V = V.flatten()
Z = Z.flatten()
ax.tricontour(H, V, Z, levels, cmap=cmap)
ax.plot(H.flatten()[::pde], V.flatten()[::pde], linestyle='None', marker='.', color='.75', alpha=0.5, zorder=1, markersize=4)
if setlims:
ax.set_xlim([-lim/2., lim/2.])
ax.set_ylim([-lim, lim])
ax.set_xlabel('AVG')
ax.set_ylabel('DIFF')
ax.set_title('Points on transformed grid, tricontour')
ax=axes[2, 0]
H = xs_rand
V = ys_rand
Z = f(xs_rand, ys_rand)
ax.tricontour(H, V, Z, levels, cmap=cmap)
ax.plot(H[::pde], V[::pde], linestyle='None', marker='.', color='.75', alpha=0.5, zorder=1, markersize=4)
if setlims:
ax.set_xlim([-lim/2., lim/2.])
ax.set_ylim([-lim/2., lim/2.])
ax.set_xlabel('X')
ax.set_ylabel('Y')
ax.set_title('Points random, tricontour')
ax=axes[2, 1]
H = (xs_rand + ys_rand) / 2.
V = ys_rand - xs_rand
Z = f(xs_rand, ys_rand)
ax.tricontour(H, V, Z, levels, cmap=cmap)
ax.plot(H[::pde], V[::pde], linestyle='None', marker='.', color='.75', alpha=0.5, zorder=1, markersize=4)
if setlims:
ax.set_xlim([-lim/2., lim/2.])
ax.set_ylim([-lim, lim])
ax.set_xlabel('AVG')
ax.set_ylabel('DIFF')
ax.set_title('Points random transformed, tricontour')
fig.tight_layout()
回答by Nicholas Hamilton
Well if you are prepared to deviate from Python into its competitor, R, I have just submitted a package to CRAN (should be available tomorrow or the next day), which conducts contouring on non-regular grids -- the following can be achieved in a few lines of code:
好吧,如果你准备从 Python 转向它的竞争对手 R,我刚刚向 CRAN 提交了一个包(应该明天或第二天可用),它在非常规网格上进行轮廓绘制——以下可以实现几行代码:
library(contoureR)
set.seed(1)
x = runif(100)
y = runif(100)
z = sin(x) + cos(y)
df = getContourLines(x,y,z,binwidth=0.0005)
ggplot(data=df,aes(x,y,group=Group)) +
geom_polygon(aes(fill=z)) +
scale_fill_gradient(low="blue",high="red") +
theme_bw()
Which produces the following:
产生以下结果:
If you want a more regular grid, and can afford a bit of extra computation time:
如果你想要一个更规则的网格,并且可以负担一些额外的计算时间:
x = seq(0,1,by=0.005)
y = seq(0,1,by=0.005)
d = expand.grid(x=x,y=y)
d$z = with(d,sin(x) + cos(y))
df = getContourLines(d,binwidth=0.0005)
ggplot(data=df,aes(x,y,group=Group)) +
geom_polygon(aes(fill=z)) +
scale_fill_gradient(low="blue",high="red") +
theme_bw()
The fuzzy edges in the above, I know how to resolve and should be fixed for the next version of the software....
上面的模糊边缘,我知道如何解决,应该在软件的下一个版本中修复....

