Python imshow:如何将两个<class'matplotlib.image.axesimage'=“”>合并为一个?

时间:2017-01-29 07:24:49

标签: python class matplotlib merge imshow

我希望我的函数在显示两个< class 'matplotlib.image.AxesImage' > < class 'matplotlib.image.AxesImage' >之后返回单个imshow类型的对象:

def merge_class(array1,array2):
    plt.imshow(array1)
    plt.imshow(array2)
    return ?

我该怎么做?

我听说我可以保存整个数字,然后在我的程序中调用该文件,但我想避免这种情况。

我也看到我可以合并这些对象,但我不明白他们做了什么:Python : How to "merge" two class

编辑1:我想知道,因为我正在制作动画,而且一帧有两层:一张图片和一张数组。

movie.append([plt.imshow(merge_class(array1,array2), animated=True, interpolation='none', origin='lower')])

电影列表中的对象必须是< class 'matplotlib.image.AxesImage' >,如果我只在函数中返回plt.show(),则会返回None

编辑2:我正在模拟森林大火。

在数组forestforest_fire中:

  • no tree = 0.0
  • 非燃烧树= 1.0
  • 燃烧树= 2.0

set_on_fire函数返回一个新的林,坐标(i,j)处的树着火。

如果至少有一个非刻录树可以刻录,则check_fire函数返回True。

spreading_fire函数返回一个新的森林,其中可以燃烧的树木着火。

以下是代码的一部分:

# maido is the name of a mountain and a forest

def img_maido(img_file,forest):
    fig, axes = plt.subplots()

    # 1) Opening the picture as an array
    img_array = plt.imread(img_file)
    img = np.copy(img_array[::-1,:,:]) # I flip it because it is upside down

    # 2) Hiding all the 'no tree' values (0.0)
    forest = np.ma.masked_where(forest == 0.0, forest) # The array is transparent at each one of the 'no tree' values position (0.0)

    # 3) The 'non-burning tree' values (1.0) are green and the 'burning tree' values (2.0) are red
    cmap = ListedColormap(['green','red'], 'indexed')

    # 4) Displaying the array 'img' of the mountain and the array 'forest' of the forest above it
    plt.imshow(forest,zorder=1, cmap=cmap, origin='lower')
    plt.imshow(img,zorder=0, origin='lower')

    return ? # Here is my issue


def fire_animation(img_file,forest,i,j,wind):
    fig, axes = plt.subplots()
    movie = []    

    # 1) Initialization
    forest_fire = set_on_fire(forest,i,j) # I put a 'burning tree' value (2.0) in the array 'forest' at the coordinates (i,j)
    movie.append([plt.imshow(img_maido(img_file,forest_fire), animated=True, cmap=cmap, interpolation='none', origin='lower')])
    plt.draw()

    # 2) Spread of fire
    while check_fire(foret,wind):
        forest_fire = spreading_fire(forest_fire,wind)
        movie.append([plt.imshow(img_maido(img_file,forest_fire), animated=True, interpolation='none', origin='lower')])
        plt.draw()

    # 3) Animation
    ani = animation.ArtistAnimation(fig, movie, interval=100, blit=True, repeat_delay=100)

    plt.draw()
    plt.show()

1 个答案:

答案 0 :(得分:0)

在这种情况下似乎没有理由使用数组来附加艺术家。您可以简单地使用一个为每次迭代更改数组的函数。

在下面的示例中,我们创建一个图形和一个轴,并将两个数组绘制成它们。每个图像都保存在一个变量中。

然后我们创建一个重复调用函数burn的动画。在这个函数中,我们操作其中一个数组并将新数据设置为其中一个图像,而另一个则不受影响。然后,更改的图像是此函数的返回值。注意,返回值后的,。这个逗号使返回值成为一个序列,这意味着,如果我们愿意,我们也可以更改两个图像并返回两者。但是,这不是必需的,因为在我们的情况下背景不会改变。

import matplotlib.pyplot as plt
import matplotlib.animation
import numpy as np

x = np.linspace(0,40)
X,Y = np.meshgrid(x,x)

static_array = (X/40.)**2+(Y/30.)**2 

dynamic_array = np.floor(np.random.random(X.shape)*1.1)
masked_dynamic_array = np.ma.masked_where(dynamic_array <=0.7 , dynamic_array)

fig, ax = plt.subplots()

static_image =  ax.imshow(static_array, cmap="terrain")
dynamic_image = ax.imshow(dynamic_array, cmap="magma")

def burn(i):
    rand = (np.random.random(X.shape)-0.3)
    new = dynamic_array + 0.1*rand
    dynamic_array[:,:] = new/new.max()
    masked_dynamic_array = np.ma.masked_where(dynamic_array <=0.7 , dynamic_array)
    dynamic_image.set_data(masked_dynamic_array)
    return dynamic_image,

ani = matplotlib.animation.FuncAnimation(fig, burn, interval=100, blit=True)

plt.show()

enter image description here

<小时/> 如果迭代次数未知,您可以先运行模拟,将生成的数组存储在列表中。完成后,使用此列表的长度作为动画帧数。

import matplotlib.pyplot as plt
import matplotlib.animation
import numpy as np

x = np.linspace(0,40)
X,Y = np.meshgrid(x,x)

static_array = (X/40.)**2+(Y/30.)**2 
dynamic_array = np.floor(np.random.random(X.shape)*1.1)


fig, ax = plt.subplots(figsize=(4,4))


static_image =  ax.imshow(static_array, cmap="terrain")
dynamic_image = ax.imshow(dynamic_array, cmap="magma", vmin=0., vmax=4.)

ims = []
while dynamic_array.mean() < 1.5:
    rand = (np.random.random(X.shape)-0.4)
    new = dynamic_array + 0.085*rand
    new[new > 4] = 4.
    dynamic_array[:,:] = new
    masked_dynamic_array = np.ma.masked_where(dynamic_array <=0.7 , dynamic_array)
    ims.append(masked_dynamic_array)

def burn(i):
    dynamic_image.set_data(ims[i])
    return dynamic_image,

plt.tight_layout()    
ani = matplotlib.animation.FuncAnimation(fig, burn, frames=len(ims), interval=100, blit=True)
ani.save(__file__+'.gif', writer='imagemagick', fps=10)
plt.show()