本文介绍了pcolormesh的动画()与mpl_toolkit.basemap给属性错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图动画在底图地图一些密度数据。下面的方法,因为在做[这太问题] [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 方法应该需要一个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 your FuncAnimation() call.

  • I was also experiencing problems when I set the quad artist attribute animated to True. 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 first pcolormesh() 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给属性错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-30 06:11