网格数据绘制过程中的误差——x的长度必须是z中的列数,y的长度必须是行数

时间:2021-06-02 16:12:12

This question is a follow on from a previous problem I'm having with contouring data points that is detailed here.

这个问题是我之前遇到的一个问题的后续问题。

[ValueError: invalid shape for input data points in griddata operation

[ValueError: griddata操作中输入数据点形状无效

After executing the griddata successfully, which required x and y as 1D and z to be a 2D array, I get the following error in relation to contour module:

成功执行griddata后,要求x、y为1D, z为2D数组,对于轮廓模块,我得到如下错误:

"TypeError: Length of x must be number of columns in z, and length of y must be number of rows."

"TypeError: x的长度必须是z中的列数,y的长度必须是行数。"

Which logically makes sense to me, as the X,Y position of Z must be known for the correct datum to be input. Short of making a square 2D array with NaN for all positions other than the points which contain Z data, is there a more elegant solution?

这在逻辑上对我来说是有意义的,因为Z的X,Y位置必须为输入正确的基准点所知道。除了包含Z数据的点之外,对于所有位置使用NaN制作一个正方形的二维数组,还有什么更好的解决方案吗?

I would assume that the griddata being generated incorporates some kind of xy locating for z on an indexing basis, however this may not be the case and infact xy locations may need to be specified precisely in an array. This seems to be doubling up to me and something I would presume the griddata module would handle.

我假设生成的griddata合并了某种基于索引的z的xy定位,但是这可能不是事实,实际上xy定位可能需要在数组中精确地指定。这对我来说似乎是双倍的,我认为griddata模块可以处理这些问题。

If anyone can shed light on the correct process for contouring from griddata, it would be helpful.

如果任何人都能从griddata中找到轮廓的正确过程,这将是很有帮助的。

As always, thank you for your time and assistance.

一如既往,感谢您的时间和帮助。

import numpy as np
from scipy.interpolate import griddata
import matplotlib.pyplot as plt
import matplotlib.mlab as ml
import numpy.ma as ma
from numpy.random import uniform, seed
from numpy import genfromtxt

my_data = genfromtxt('WaterTable.csv', delimiter=',')
# Data imported as a 2D array
z = my_data[1:,2:3]

#Data imported as 1D array
x = my_data[1:, 0]
y = my_data[1:, 1]

xmax = max(x)
xmin = min(x)
ymax = max(y)
ymin = min(y)

# Prepares for import to griddata
xi = np.linspace(xmin, xmax, 2000)
yi = np.linspace(ymin, ymax, 2000)

# grids data
zi = griddata((x, y), z, (xi, yi), method='cubic')
# contour the gridded data

CS = plt.contour(xi,yi,zi,15,linewidths=0.5,colors='k')
CS = plt.contourf(xi,yi,zi,15,cmap=plt.cm.jet)
plt.colorbar() # draw colorbar

# plot data points.

plt.scatter(x,y,marker='o',c='b',s=5)
plt.xlim(-2,2)
plt.ylim(-2,2)
plt.title('griddata test (%d points)' % npts)
plt.show()

Error thrown:

错误扔:

Traceback (most recent call last):
File "C:/Users/Hp/PycharmProjects/GISdev/Irregular_Grid04.py", line 30, in <module>
CS = plt.contour(xi,yi,zi,15,linewidths=0.5,colors='k')
File "C:\Python27\lib\site-packages\matplotlib\pyplot.py", line 2188, in contour
ret = ax.contour(*args, **kwargs)
File "C:\Python27\lib\site-packages\matplotlib\axes.py", line 7316, in contour
return mcontour.QuadContourSet(self, *args, **kwargs)
File "C:\Python27\lib\site-packages\matplotlib\contour.py", line 1106, in __init__
ContourSet.__init__(self, ax, *args, **kwargs)
File "C:\Python27\lib\site-packages\matplotlib\contour.py", line 700, in __init__
self._process_args(*args, **kwargs)
File "C:\Python27\lib\site-packages\matplotlib\contour.py", line 1119, in _process_args
x, y, z = self._contour_args(args, kwargs)
File "C:\Python27\lib\site-packages\matplotlib\contour.py", line 1166, in _contour_args
x,y,z = self._check_xyz(args[:3], kwargs)
File "C:\Python27\lib\site-packages\matplotlib\contour.py", line 1208, in _check_xyz
"and length of y must be number of rows.")
TypeError: Length of x must be number of columns in z, and length of y must be number of rows.

2 个解决方案

#1


1  

Rereading your question I realized that gridata is calculating one zi value for each (xi,yi) pair, ie 2000. But those values are just linear. - generated by linspace. To contour they need to form a Cartesian space. That's what my example does. Your xi, yi valuus need to go through meshgrid (or equivalent) before being passed to gridata.

重读你的问题,我意识到gridata正在计算每个(xi,yi)对的zi值。但这些值都是线性的。——由linspace生成。对于轮廓,他们需要形成一个笛卡尔空间。这就是我的例子。在传递给gridata之前,你的xi, yi valuus需要经过网格网格(或等效)。

My contouring example is valid, but my guess as to what is wrong with your shapes was off. The problem is before gridata, not after.

我的轮廓示例是有效的,但是我的猜测是关于您的形状的错误。问题是在gridata之前,而不是之后。


A basic step when debugging numpy code is to print the shape of arrays at various points, especially when the error talks about their length. Another is to construct simple test cases in an interactive shell (I use Ipython).

调试numpy代码时的一个基本步骤是在不同的点上打印数组的形状,特别是当错误谈到数组的长度时。另一种方法是在交互式shell中构建简单的测试用例(我使用Ipython)。

Let's try the contour step:

让我们试试轮廓步骤:

In [32]: xi=np.arange(10)    
In [33]: yi=np.arange(15)
In [34]: zi=xi[:,None]+yi[None,:]
In [35]: zi.shape
Out[35]: (10, 15)

zi is a function of xi and yi - the 1st and 2nd dimensions

zi是xi和yi的函数- 1维和2维

** that's 10 x 15, not just 10 or 15 **

**是10 * 15,而不是10或15 **

In [36]: plt.contour(xi,yi,zi)
....
TypeError: Length of x must be number of columns in z,
and length of y must be number of rows.

That's your error message right?

这就是你的错误信息,对吧?

Try it again, but using the transpose of zi:

再试一次,用zi的转置:

In [37]: plt.contour(xi,yi,zi.T)
Out[37]: <matplotlib.contour.QuadContourSet instance at 0xa32726c>

works. So does plt.contour(yi,xi,zi); and plt.contour(zi) (of course axis labels are wrong).

的工作原理。那么plt.contour(咦,xi,子);轮廓(zi)(当然轴标签是错误的)。

Without going to all the work of setting up a my_data that will work in griddata, I suspect this switch of xi and yi (of the .T) will solve things.

我不需要设置一个在griddata中工作的_mydata,我怀疑xi和yi (. t)的这个开关将解决问题。

But! you are using linspace(...,2000) for both, so maybe they have the same length and zi is square.

但是!你用linspace(…,2000)来表示这两种情况,所以它们的长度可能是一样的,zi是正方形的。

Another possibility is that z has a wrong shape. I'm guessing x and y are (n,), and z is (n,1) (due to the 2:3). How does that pass through the griddata to zi? I don't have a working example for griddata so can't test it.

另一种可能是z的形状不对。我猜x和y是(n,) z是(n,1)(由于2:3)如何将griddata传递给zi?我没有griddata的工作示例,所以不能测试它。

You need to print the shape of all of these arrays. Otherwise we have to deduce from experience, or run our own dummy test cases. We shouldn't have to go to all that work to help you debug your code.

您需要打印所有这些数组的形状。否则我们必须从经验中推断,或者运行我们自己的虚拟测试用例。我们不需要做所有这些工作来帮助您调试代码。

#2


0  

Thank you for all the help and advice on debugging numpy arrays. Just wanted to post up the working code for this. In the end I used ravel to reduce Z to a 2D array. Without ravel Zi returns a shape of (2000, 2000, 1) instead of (2000, 2000). Ravel removes the extra dimension which was the problem. I think passing through meshgrid may have a similar effect.

感谢您对调试numpy数组的所有帮助和建议。我只是想发布这个的工作代码。最后,我使用ravel将Z减少到2D数组。如果没有ravel Zi,返回的形状为(2000,2000,1)而不是(2000,2000)。拉威尔去掉了问题所在的额外维度。我认为通过网格网格可以产生类似的效果。

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

my_data = genfromtxt('WaterTable.csv', delimiter=',')

# Data imported as a 2D array
z = my_data[1:,2:3]

#Data imported as 1D array
x = my_data[1:, 0]
y = my_data[1:, 1]

xmax = max(x)
xmin = min(x)
ymax = max(y)
ymin = min(y)

# Prepares for import to griddata
xi = np.linspace(xmin, xmax, 2000)
yi = np.linspace(ymin, ymax, 2000)

# grids data
zi = griddata((x, y), z.ravel(), (xi[None,:], yi[:,None]), method='cubic')
# contour the gridded data

print(zi.shape)
print(xi.shape)
print(yi.shape)

CS = plt.contour(xi,yi,zi,15,linewidths=0.5,colors='k')
CS = plt.contourf(xi,yi,zi,15,cmap=plt.cm.jet)
plt.colorbar() # draw colorbar

# plot data points.
plt.scatter(x,y,marker='o',c='b',s=5)
plt.xlim(xmin, xmax)
plt.ylim(ymin, ymax)
plt.show()

#1


1  

Rereading your question I realized that gridata is calculating one zi value for each (xi,yi) pair, ie 2000. But those values are just linear. - generated by linspace. To contour they need to form a Cartesian space. That's what my example does. Your xi, yi valuus need to go through meshgrid (or equivalent) before being passed to gridata.

重读你的问题,我意识到gridata正在计算每个(xi,yi)对的zi值。但这些值都是线性的。——由linspace生成。对于轮廓,他们需要形成一个笛卡尔空间。这就是我的例子。在传递给gridata之前,你的xi, yi valuus需要经过网格网格(或等效)。

My contouring example is valid, but my guess as to what is wrong with your shapes was off. The problem is before gridata, not after.

我的轮廓示例是有效的,但是我的猜测是关于您的形状的错误。问题是在gridata之前,而不是之后。


A basic step when debugging numpy code is to print the shape of arrays at various points, especially when the error talks about their length. Another is to construct simple test cases in an interactive shell (I use Ipython).

调试numpy代码时的一个基本步骤是在不同的点上打印数组的形状,特别是当错误谈到数组的长度时。另一种方法是在交互式shell中构建简单的测试用例(我使用Ipython)。

Let's try the contour step:

让我们试试轮廓步骤:

In [32]: xi=np.arange(10)    
In [33]: yi=np.arange(15)
In [34]: zi=xi[:,None]+yi[None,:]
In [35]: zi.shape
Out[35]: (10, 15)

zi is a function of xi and yi - the 1st and 2nd dimensions

zi是xi和yi的函数- 1维和2维

** that's 10 x 15, not just 10 or 15 **

**是10 * 15,而不是10或15 **

In [36]: plt.contour(xi,yi,zi)
....
TypeError: Length of x must be number of columns in z,
and length of y must be number of rows.

That's your error message right?

这就是你的错误信息,对吧?

Try it again, but using the transpose of zi:

再试一次,用zi的转置:

In [37]: plt.contour(xi,yi,zi.T)
Out[37]: <matplotlib.contour.QuadContourSet instance at 0xa32726c>

works. So does plt.contour(yi,xi,zi); and plt.contour(zi) (of course axis labels are wrong).

的工作原理。那么plt.contour(咦,xi,子);轮廓(zi)(当然轴标签是错误的)。

Without going to all the work of setting up a my_data that will work in griddata, I suspect this switch of xi and yi (of the .T) will solve things.

我不需要设置一个在griddata中工作的_mydata,我怀疑xi和yi (. t)的这个开关将解决问题。

But! you are using linspace(...,2000) for both, so maybe they have the same length and zi is square.

但是!你用linspace(…,2000)来表示这两种情况,所以它们的长度可能是一样的,zi是正方形的。

Another possibility is that z has a wrong shape. I'm guessing x and y are (n,), and z is (n,1) (due to the 2:3). How does that pass through the griddata to zi? I don't have a working example for griddata so can't test it.

另一种可能是z的形状不对。我猜x和y是(n,) z是(n,1)(由于2:3)如何将griddata传递给zi?我没有griddata的工作示例,所以不能测试它。

You need to print the shape of all of these arrays. Otherwise we have to deduce from experience, or run our own dummy test cases. We shouldn't have to go to all that work to help you debug your code.

您需要打印所有这些数组的形状。否则我们必须从经验中推断,或者运行我们自己的虚拟测试用例。我们不需要做所有这些工作来帮助您调试代码。

#2


0  

Thank you for all the help and advice on debugging numpy arrays. Just wanted to post up the working code for this. In the end I used ravel to reduce Z to a 2D array. Without ravel Zi returns a shape of (2000, 2000, 1) instead of (2000, 2000). Ravel removes the extra dimension which was the problem. I think passing through meshgrid may have a similar effect.

感谢您对调试numpy数组的所有帮助和建议。我只是想发布这个的工作代码。最后,我使用ravel将Z减少到2D数组。如果没有ravel Zi,返回的形状为(2000,2000,1)而不是(2000,2000)。拉威尔去掉了问题所在的额外维度。我认为通过网格网格可以产生类似的效果。

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

my_data = genfromtxt('WaterTable.csv', delimiter=',')

# Data imported as a 2D array
z = my_data[1:,2:3]

#Data imported as 1D array
x = my_data[1:, 0]
y = my_data[1:, 1]

xmax = max(x)
xmin = min(x)
ymax = max(y)
ymin = min(y)

# Prepares for import to griddata
xi = np.linspace(xmin, xmax, 2000)
yi = np.linspace(ymin, ymax, 2000)

# grids data
zi = griddata((x, y), z.ravel(), (xi[None,:], yi[:,None]), method='cubic')
# contour the gridded data

print(zi.shape)
print(xi.shape)
print(yi.shape)

CS = plt.contour(xi,yi,zi,15,linewidths=0.5,colors='k')
CS = plt.contourf(xi,yi,zi,15,cmap=plt.cm.jet)
plt.colorbar() # draw colorbar

# plot data points.
plt.scatter(x,y,marker='o',c='b',s=5)
plt.xlim(xmin, xmax)
plt.ylim(ymin, ymax)
plt.show()