使用Matplotlib-Basemap和Xarray绘制经纬度网格线

3

我有一个xarray DataArray da,其中包含一个看起来像这样的爱尔兰数据切片:

<xarray.DataArray 'co2' (lat: 733, lon: 720)>
array([[nan, nan, nan, ..., nan, nan, nan],
   [nan, nan, nan, ..., nan, nan, nan],
   [nan, nan, nan, ..., nan, nan, nan],
   ...,
   [nan, nan, nan, ..., nan, nan, nan],
   [nan, nan, nan, ..., nan, nan, nan],
   [nan, nan, nan, ..., nan, nan, nan]])
Coordinates:
  * lat      (lat) float32 49.9 49.908333 49.916664 49.924995 49.933327 ...
  * lon      (lon) float32 -11.0 -10.991667 -10.983334 -10.975 -10.966667 ...

我可以这样映射它:
import matplotlib.pyplot as plt
import xarray
import os
from mpl_toolkits.basemap import Basemap, cm

m= Basemap(projection='cyl',lat_0=ds.co2.lat[0],lon_0=ds.co2.lon[len(ds.co2.lon)/2])
m.drawcoastlines()
da.plot()

问题在于经纬网格线没有绘制。

enter image description here

当我使用meridians命令时:
meridians = np.arange(10.,351.,20.)
m.drawmeridians(meridians,labels=[True,False,False,True])

我得到以下错误:
ValueError: dimensions () must have the same length as the number of data dimensions, ndim=1

我不知道接下来该尝试什么。

编辑:完整的错误跟踪:

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-46-45a293c8bb99> in <module>()
  4 
  5 # draw grid plots
----> 6 m.drawmeridians(np.arange(-8.0,2.0,1.0),labels=[1,0,0,0]) #longitudes
      7 m.drawparallels(np.arange(51.0,59.0,1.0),labels=[0,0,0,1]) #latitudes
      8 

C:\Users\AppData\Local\Continuum\Anaconda\lib\site-    packages\mpl_toolkits\basemap\__init__.pyc in drawmeridians(self, meridians, color, linewidth, zorder, dashes, labels, labelstyle, fmt, xoffset, yoffset, ax, latmax, **kwargs)
   2593             # don't really know why, but this appears to be needed to
   2594             # or lines sometimes don't reach edge of plot.
-> 2595             testx = np.logical_and(x>=self.xmin-3*xdelta,x<=self.xmax+3*xdelta)
   2596             x = np.compress(testx, x)
   2597             y = np.compress(testx, y)

C:\Users\\AppData\Local\Continuum\Anaconda\lib\site-packages\xarray\core\dataarray.pyc in func(self, other)
   1550 
   1551             variable = (f(self.variable, other_variable)
-> 1552                         if not reflexive
   1553                         else f(other_variable, self.variable))
   1554             coords = self.coords._merge_raw(other_coords)

C:\Users\\AppData\Local\Continuum\Anaconda\lib\site-packages\xarray\core\variable.pyc in func(self, other)
   1164                         if not reflexive
   1165                         else f(other_data, self_data))
-> 1166             result = Variable(dims, new_data)
   1167             return result
   1168         return func

C:\Users\\AppData\Local\Continuum\Anaconda\lib\site-packages\xarray\core\variable.pyc in __init__(self, dims, data, attrs, encoding, fastpath)
    255         """
    256         self._data = as_compatible_data(data, fastpath=fastpath)
--> 257         self._dims = self._parse_dimensions(dims)
    258         self._attrs = None
    259         self._encoding = None

C:\Users\\AppData\Local\Continuum\Anaconda\lib\site-packages\xarray\core\variable.pyc in _parse_dimensions(self, dims)
    364             raise ValueError('dimensions %s must have the same length as the '
    365                              'number of data dimensions, ndim=%s'
--> 366                              % (dims, self.ndim))
    367         return dims
    368 

ValueError: dimensions () must have the same length as the number of data dimensions, ndim=1

你能否以某种方式分享数据的pickle文件? - Shir
@shir 我可以给你发送数据的链接吗?它的大小超过2GB。 - Pad
3
您能否只发送一小部分内容呢? :) 我猜如果是1MB也会存在问题 :) - Shir
我会支持@Shir的请求,希望提供包含数据的最小工作示例。如果您只有几个点的问题,请在此处包含它们-这样人们可以确认是否存在相同的问题,并尝试实现他们的想法来解决它。 - kabdulla
你的小数据集对我来说实际上是可行的。你可以尝试使用它并告诉我是否有效吗? - Shir
显示剩余6条评论
2个回答

3

建议使用cartopy替代Basemap。相关问题请参见此处


谢谢,但是这个代码给我报错了:“ImportError: DLL load failed: The specified module could not be found.” 我已经重新安装了所有的包并更新了它们,但错误仍然存在 :( - Pad
尝试使用Python 3.6时,我遇到了错误“ValueError:在制作分面图时无法使用轴。” - Pad

1

简而言之- 我使用了你的代码和数据集,没有遇到问题,我们来找出原因。

我使用了你提供的小型数据集和这段代码:

ds=xarray.open_dataset(r"C:\Users\SHIR\Downloads\OneYear.nc")
da=ds.co2
m= Basemap(projection='cyl',lat_0=ds.co2.lat[0],lon_0=ds.co2.lon[len(ds.co2.lon)/2])
m.drawcoastlines()
da.plot()
plt.show()

我得到了这张图表:

enter image description here

在添加经线时,使用以下代码:


ds=xarray.open_dataset(r"C:\Users\SHIR\Downloads\OneYear.nc")
da=ds.co2
m= Basemap(projection='cyl',lat_0=ds.co2.lat[0],lon_0=ds.co2.lon[len(ds.co2.lon)/2])
m.drawcoastlines()
meridians = np.arange(10.,351.,20.)
m.drawmeridians(meridians,labels=[True,False,False,True])
da.plot()
plt.show()

我得到了-

enter image description here

我能想到导致我们之间差异的原因有以下几点:

第一,数据集较小,请尝试您发给我的小数据集,并让我知道是否再次出现错误。

第二,包和版本。我使用的是Python 2.7。以前我没有安装basemap,所以我尝试使用conda进行安装,但遇到了很多问题。最终,我使用conda卸载了matplotlib(conda uninstall matplotlib),然后使用pip重新安装了它(pip install matplotlib --upgrade --force-reinstall),并像this answer中描述的那样手动安装了basemap。我使用的是basemap‑1.2.0‑cp27‑cp27m‑win_amd64.whl文件。

我真的不确定这种方式是否明智,也不确定是否弄乱了conda,但这是我唯一可行的方法。也许您可以先尝试仅卸载basemap而非matplotlib(我之前卸载了matplotlib是因为我已经把它搞糟了...)


1
非常感谢您的帮助。我认为您关于软件包问题的看法是正确的,Basemap似乎会导致其他脚本出现问题。为了避免影响其他代码,我可能会完全避免使用Basemap!不过,您的回答解决了我的问题! - Pad

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接