matplotlib翻转x和y

时间:2015-08-05 14:41:09

标签: python arrays performance numpy matplotlib

我对matplotlib的工作原理有疑问。基本上,我想在我的图像中翻转x和y,就像this person asked一样。

但是,我不想在发送之前转换数组。

我认为这会导致性能下降。现在这是我的推理。我的猜测是,matplotlib可能会尝试通过迭代两者中快速变化的索引来将图像从numpy复制到matplotlib(其中快速变化的索引在这里被假定为导致访问物理内存中的连续元素的索引)。如果我转置数组,可能会发生以下两种情况之一:

  1. matplotlib认为内存中快速变化的索引不再是真的,因此它将不再以内存连续的方式访问numpy数组,导致读取速度变慢。 (即numpy只是改变它" s"查看"进入矩阵)
  2. Numpy数组实际上被复制到一个新的数组中,其中快速变化的索引被转置。读入matplotlib很快就会以将新矩阵复制到内存中为代价。
  3. 在我的情况下,这两种情况都不理想,因为我希望获得相当高的刷新率。数组是从已存储在以这种方式存储的硬盘驱动器上的图像加载的。

    如果我的假设是正确的,是否有一些方法可以让matplotlib改变其快速变化的索引以适应图像的情况?我相信这将是一个非常有用的功能。

    我希望传达我的推理路线。我想确保链中的每个读写都是内存连续的,从硬盘驱动器到numpy数组到matplotlib。我相信,简单地找到(或提供将来)matplotlib的选项来改变它的排序方法可以节省时间。

    我绝对愿意接受其他解决方案。如果我错过了一些明显的东西,我想听听它,谢谢: - )

    修改:感谢您的评论。我相信你是对的,我应该事先做一些测试。我有一个有趣的结果。转置似乎比非转置更快。由于numpy引用只是对数组的一个视图,因此matplotlib可以利用它来巧妙地决定是否在最后一分钟进行转置?这个结果表明,那个或我的代码有一个缺陷(这是非常可能的)。说真的,如果真的那么好,那就好了。工作matplotlib开发人员! : - )

    以下是数据:

    图1:转置图像(蓝色)和非转置图像(绿色)。每个数据点是按顺序绘制所有10帧所用的时间。这重复100次。在这些实验期间我没有使用机器。

    Figure 1

    图2:相同图形的缩放

    Figure 2

    代码(它的粗略,学习和有限的时间花在这上面。我运行第一个1000帧,关闭窗口,取消注释第二个动画,评论第一个并再次运行1000帧然后绘制了两个。):

    `   
        from matplotlib.pyplot import *
        from matplotlib import animation
        from time import time
        import pylab
        import numpy as np
    
        data = np.random.random((10,1000,1000))
    
        ion()
        fig = figure(0)
    
        im = imshow(data[0,:,:])
    
        data[0,:,:] *= 0
    
        time1 = time()
        time0 = time()
        timingarraynoT =  np.zeros(100)
        timingarrayT =  np.zeros(100)
    
        def animatenoT(i):
            global time0,time1,timingarraynoT
            if(i%10==0):
                time0 = time()
            if(i%10 == 9):
                time1 = time()
                #print("Time for 10 frames: {}".format(time1-time0))
                timingarraynoT[i/10] = time1-time0
            im.set_data(data[i%10,:,:])
            if(i == 1000):
                return -1
            return im
    
        def animateT(i):
            global time0,time1,timingarrayT
            if(i%10==0):
                time0 = time()
            if(i%10 == 9):
                time1 = time()
                #print("Time for 10 frames: {}".format(time1-time0))
                timingarrayT[i/10] = time1-time0
            im.set_data(data[i%10,:,:].T)
            if(i == 1000):
                return -1
            return im
    
        #anim = animation.FuncAnimation(fig, animateT,interval=0)
        anim = animation.FuncAnimation(fig, animatenoT,interval=0)
    `

0 个答案:

没有答案