问题描述
我试图动画在底图
地图一些密度数据。下面的方法,因为在做[这太问题] [1],我得到以下错误:
/usr/local/lib/python2.7/dist-packages/matplotlib/collections.pyc在update_scalarmappable(个体经营)
如果627是self._A无:
628回
- >如果629&self._A.ndim GT; 1:
630提高ValueError错误('集合只能映射秩1阵列)
631如果不是self.check_update(阵):AttributeError的:'名单'对象有没有属性'NDIM
如果我不是设置初始化数据()
与 self.quad.set_array空值(self.z.ravel())与正在动画没有数据
,我结束了两个绘制的地图。
这是任何人都可以阐明我做错了会大大AP preciated任何光线。谢谢!
例如code
高清plot_pcolor(LONS,拉特): 类UpdateQuad(对象): 高清__init __(自我,斧,map_object,LONS,拉特):
self.ax = AX
self.m = map_object
self.lons = LONS
self.lats =拉特 self.ydim,self.xdim = lons.shape self.z = np.zeros((self.ydim-1,self.xdim-1)) X,Y = self.m(LONS,拉特)
self.quad = ax.pcolormesh(X,Y,self.z,CMAP = plt.cm.Reds) 高清的init(个体经营):
打印更新的init
self.quad.set_array([])
回报self.quad 高清__call __(自我,我): 数据= np.zeros((self.ydim-1,self.xdim-1)) 因为我在范围内(self.ydim-1):
对于在范围Ĵ(self.xdim-1):
数据[I,J] = random.random()+4 self.quad.set_array(data.ravel())
回报self.quad 图= plt.figure()
AX = fig.add_axes([0.1,0.1,0.8,0.8]) M =底图(宽= 2000000,身高= 2000000,
分辨率='L',投影='laea',\\
lat_ts = 10。,\\
lat_0 = 64,lon_0 = 10,AX = AX) m.fillcontinents() UD = UpdateQuad(斧,男,LONS,拉特) 动画= animation.FuncAnimation(图,UD,=的init_func ud.init,
帧= 20,的blit =假) plt.show()如果__name__ =='__main__':
进口matplotlib.pyplot如PLT
进口matplotlib.animation动画
从mpl_toolkits.basemap进口底图
导入numpy的是NP
进口随机 LONS = np.linspace(-5,25,NUM = 25):50]
拉特= np.linspace(56,71,NUM = 25):50]
LONS,拉特= np.meshgrid(LONS,拉特) plot_pcolor(LONS,拉特)
它看起来像 set_data code>方法应该需要一个ndarray(不知道为什么我跟随的例子是正常工作)。
所以在的init()
功能,你应该使用 quad.set_array(np.array([]))
而非 quad.set_array([])
。
其他问题需要注意的
-
正如前面提到的,你也想设置
的blit =假
在FuncAnimation()
电话。 -
我也遇到问题时,我设置了四
艺术家
属性动画
到真
。离开那个是(即quad.set_animated(假)
,这是默认反正)。 -
如果您没有在第一个
pcolormesh指定通过
呼叫时,将根据您传递(在我的情况下空)的数据,这导致我越来越空白的动画设置。根据您将在我的情况下pvented这个问题的初始调用$ P $后来动画数据设置它们。规范
边界() -
pcolormesh()
取边界位置数据字段,这应该是在数据数组的Y和X尺寸+1。如果数据数组(大于或更大)相等的位置数据的尺寸,pcolormesh()
会忽略这个边界之外要求的任何数据。我以为我的数据会出现只通过一个网格偏移量,但一切都没有怪诞之前,我通过正确的边界位置。见我的另一个问题,计算这些。 -
matplotlib
的旧版本没有很好的错误报告。我建议升级到最新版本,如果这是一个选择。
一些随机的故障排除
更新后 matplotlib
和底图
,并试图在现有的绘图程序来实现这一点,我收到以下错误
ValueError错误:在短跑列表中的所有值必须为正
我首先想到它与我的 pcolormesh做()
的对象,但我花了太长时间地发现,这是由于我的previous设置在几许
在我的 m.drawmeridians属性()
来电短线= [1, 0]
了坚实的经络。在 matplotlib
新版本的给这个错误。设置实线为冲刺新的prefered方法
属性是破折号=(无,无)
,这是我不喜欢的。
生成的动画
$ C以上输出$ C例如
高清plot_pcolor(LONS,拉特): 类UpdateQuad(对象): 高清__init __(自我,斧,map_object,LONS,拉特):
self.ax = AX
self.m = map_object
self.lons = LONS
self.lats =拉特
VMIN = 0
VMAX = 1
self.ydim,self.xdim = lons.shape self.z = np.zeros((self.ydim-1,self.xdim-1)) 水平= MaxNLocator(nbins = 15).tick_values(最小值,VMAX)
CMAP = plt.cm.cool
规范= BoundaryNorm(水平,ncolors = cmap.N,夹= TRUE)
X,Y = self.m(LONS,拉特) self.quad = self.ax.pcolormesh(X,Y,self.z,α-= 0.9,
标准=规范,CMAP CMAP =,
VMIN =最小值,VMAX = VMAX)
高清的init(个体经营):
打印更新的init
self.quad.set_array(np.asarray([]))
回报self.quad 高清__call __(自我,我): 因为我在范围内(self.ydim-1):
对于在范围Ĵ(self.xdim-1):
self.z [I,J] = random.random() self.quad.set_array(self.z.ravel()) 回报self.quad
无花果,AX = plt.subplots() M =底图(宽= 2000000,身高= 2000000,
分辨率='L',投影='laea',\\
lat_ts = 10。,\\
lat_0 = 64,lon_0 = 10,AX = AX) m.fillcontinents() UD = UpdateQuad(斧,男,LONS,拉特) 动画= animation.FuncAnimation(图,UD,=的init_func ud.init,
帧= 20,的blit =假) fig.tight_layout() plt.show() 返回ud.quad如果__name__ =='__main__':
进口matplotlib.pyplot如PLT
进口matplotlib.animation动画
从mpl_toolkits.basemap进口底图
导入numpy的是NP
进口随机
从matplotlib.colors进口BoundaryNorm
从matplotlib.ticker进口MaxNLocator LONS = np.linspace(-5,25,NUM = 25):50]
拉特= np.linspace(56,71,NUM = 25):50]
LONS,拉特= np.meshgrid(LONS,拉特) 四= plot_pcolor(LONS,拉特)
I am trying to animate some density data on a basemap
map. Following an approach as was done in [this SO question][1], I get the following error:
/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'
If I instead set the data in init()
with null values by self.quad.set_array(self.z.ravel())
, I end up with two plotted maps with no data being animated.
Any light that anybody could shed on what I'm doing wrong would be greatly appreciated. Thanks!
example code:
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)
It looks like the set_data
method should require an ndarray (not sure why the example I had followed was working correctly).
So in the init()
function, you should use quad.set_array(np.array([]))
rather than quad.set_array([])
.
Other problems to be aware of:
As mentioned before, you also want set
blit=False
in yourFuncAnimation()
call.I was also experiencing problems when I set the quad
artist
attributeanimated
toTrue
. Leave that be (i.e.quad.set_animated(False)
, which is the default anyway).If you do not specify the bounds via
norm
in your firstpcolormesh()
call, it will set them according to the data you pass (in my case null), which resulting in my getting blank animations. Setting them according to the data you will animate later in the initial call prevented this problem in my case.pcolormesh()
takes the bounding positions to the data field, which should be +1 in the y and x dimension of the data array. If the data array is equal (or greater than) the dimensions of the position data,pcolormesh()
will omit any data outside of this boundary requirement. I thought that my data would just appear offset by one grid cell, but everything was all whacky before I passed the correct boundary positions. See another question of mine for calculating these HERE.Older versions of
matplotlib
do not have very good error reporting. I recommend upgrading to the latest version if that is an option for you.
Some random trouble-shooting:
After updating matplotlib
and basemap
and attempting to implement this in my existing plotting routine, I received the following error:
ValueError: All values in the dash list must be positive
I first thought it had to do with my pcolormesh()
objects, but it took me way too long to discover that it was due to my previous setting of the dash
attribute in my m.drawmeridians()
call to dashes=[1,0]
for a solid meridian. In the new version of matplotlib
the handling of dashes was changed to give this error. The new prefered method for setting a solid line for the dash
attribute is dashes=(None,None)
, which I don't like.
Resulting animation:
Code example for above output:
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)
这篇关于pcolormesh的动画()与mpl_toolkit.basemap给属性错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!