我正在尝试为 basemap
map 上的一些密度数据制作动画。按照 [this SO question][1] 中的方法,我收到以下错误:
/usr/local/lib/python2.7/dist-packages/matplotlib/collections.pyc in update_scalarmappable(self)
627 if self._A is None:
628 return
--> 629 if self._A.ndim > 1:
630 raise ValueError('Collections can only map rank 1 arrays')
631 if not self.check_update("array"):
AttributeError: 'list' object has no attribute 'ndim'
如果我改为通过 self.quad.set_array(self.z.ravel())
将 init()
中的数据设置为空值,我最终会得到两个没有动画数据的绘制 map 。
如果有人能指出我做错了什么,我们将不胜感激。谢谢!
示例代码:
def plot_pcolor(lons,lats):
class UpdateQuad(object):
def __init__(self,ax, map_object, lons, lats):
self.ax = ax
self.m = map_object
self.lons = lons
self.lats = lats
self.ydim, self.xdim = lons.shape
self.z = np.zeros((self.ydim-1,self.xdim-1))
x, y = self.m(lons, lats)
self.quad = ax.pcolormesh(x, y, self.z, cmap=plt.cm.Reds)
def init(self):
print 'update init'
self.quad.set_array([])
return self.quad
def __call__(self,i):
data = np.zeros((self.ydim-1,self.xdim-1))
for i in range(self.ydim-1):
for j in range(self.xdim-1):
data[i,j]=random.random()+4
self.quad.set_array(data.ravel())
return self.quad
fig = plt.figure()
ax = fig.add_axes([0.1,0.1,0.8,0.8])
m = Basemap(width=2000000,height=2000000,
resolution='l', projection='laea',\
lat_ts=10.,\
lat_0=64.,lon_0=10., ax=ax)
m.fillcontinents()
ud = UpdateQuad(ax, m, lons, lats)
anim = animation.FuncAnimation(fig, ud, init_func=ud.init,
frames=20, blit=False)
plt.show()
if __name__ == '__main__':
import matplotlib.pyplot as plt
import matplotlib.animation as animation
from mpl_toolkits.basemap import Basemap
import numpy as np
import random
lons = np.linspace(-5.,25., num = 25)[:50]
lats = np.linspace(56., 71., num = 25)[:50]
lons,lats = np.meshgrid(lons,lats)
plot_pcolor(lons,lats)
最佳答案
看起来 set_data
方法应该需要一个 ndarray(不确定为什么我遵循的示例可以正常工作)。
所以在 init()
函数中,你应该使用 quad.set_array(np.array([]))
而不是 quad.set_array([ ])
.
其他需要注意的问题:
如前所述,您还需要在
FuncAnimation()
调用中设置blit=False
。当我将四边形
artist
属性animated
设置为True
时,我也遇到了问题。保留原样(即quad.set_animated(False)
,这是默认设置)。如果您在第一次调用
pcolormesh()
时没有通过norm
指定边界,它将根据您传递的数据(在我的case null),这导致我得到空白动画。根据稍后将在初始调用中设置动画的数据设置它们,在我的案例中避免了这个问题。pcolormesh()
获取数据字段的边界位置,在数据数组的 y 和 x 维度中应为 +1。如果数据数组等于(或大于)位置数据的维度,pcolormesh()
将忽略此边界要求之外的任何数据。我以为我的数据只会出现一个网格单元的偏移,但在我通过正确的边界位置之前一切都很糟糕。请参阅我的另一个问题以计算这些 HERE .旧版本的
matplotlib
没有很好的错误报告。如果您愿意,我建议升级到最新版本。
一些随机故障排除:
更新 matplotlib
和 basemap
并尝试在我现有的绘图例程中实现它后,我收到以下错误:
ValueError: All values in the dash list must be positive
我最初以为它与我的 pcolormesh()
对象有关,但我花了很长时间才发现这是由于我之前设置的 dash
在我的 m.drawmeridians()
调用中为 dashes=[1,0]
设置实体子午线的属性。在新版本的 matplotlib
中 the handling of dashes was changed给出这个错误。为 dash
属性设置实线的新首选方法是 dashes=(None,None)
,我不喜欢这种方法。
生成的动画:
上述输出的代码示例:
def plot_pcolor(lons,lats):
class UpdateQuad(object):
def __init__(self,ax, map_object, lons, lats):
self.ax = ax
self.m = map_object
self.lons = lons
self.lats = lats
vmin = 0
vmax = 1
self.ydim, self.xdim = lons.shape
self.z = np.zeros((self.ydim-1,self.xdim-1))
levels = MaxNLocator(nbins=15).tick_values(vmin,vmax)
cmap = plt.cm.cool
norm = BoundaryNorm(levels, ncolors=cmap.N, clip=True)
x, y = self.m(lons, lats)
self.quad = self.ax.pcolormesh(x, y, self.z, alpha=0.9,
norm=norm, cmap=cmap,
vmin=vmin, vmax=vmax)
def init(self):
print 'update init'
self.quad.set_array(np.asarray([]))
return self.quad
def __call__(self,i):
for i in range(self.ydim-1):
for j in range(self.xdim-1):
self.z[i,j]=random.random()
self.quad.set_array(self.z.ravel())
return self.quad
fig, ax = plt.subplots()
m = Basemap(width=2000000,height=2000000,
resolution='l', projection='laea',\
lat_ts=10.,\
lat_0=64.,lon_0=10., ax=ax)
m.fillcontinents()
ud = UpdateQuad(ax, m, lons, lats)
anim = animation.FuncAnimation(fig, ud, init_func=ud.init,
frames=20, blit=False)
fig.tight_layout()
plt.show()
return ud.quad
if __name__ == '__main__':
import matplotlib.pyplot as plt
import matplotlib.animation as animation
from mpl_toolkits.basemap import Basemap
import numpy as np
import random
from matplotlib.colors import BoundaryNorm
from matplotlib.ticker import MaxNLocator
lons = np.linspace(-5.,25., num = 25)[:50]
lats = np.linspace(56., 71., num = 25)[:50]
lons,lats = np.meshgrid(lons,lats)
quad = plot_pcolor(lons,lats)
关于python - 带有 mpl_toolkit.basemap 的 pcolormesh() 动画给出属性错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22700969/