简体   繁体   English

如何在matplotlib中更新pcolor?

[英]How to update pcolor in matplotlib?

I plot information from a 2D array with pcolor. 我用pcolor从2D数组中绘制信息。 however, the information in the array is changed over the iterations, and I want to update the color map dynamically, in order to visualize the changes in real time. 但是,数组中的信息在迭代过程中发生了变化,我想动态地更新颜色图,以便实时看到变化。 How can I do it in the most simple way? 我如何以最简单的方式做到这一点?

Edit - example: 编辑-示例:

from __future__ import division
from pylab import *
import random

n = 50 # number of iterations
x = arange(0, 10, 0.1)
y = arange(0, 10, 0.1)
T = zeros([100,100]) # 10/0.1 = 100
X,Y = meshgrid(x, y)

"""initial conditions"""
for x in range(100):
 for y in range(100):
  T[x][y] = random.random()

pcolor(X, Y, T, cmap=cm.hot, vmax=abs(T).max(), vmin=0)
colorbar()
axis([0,10,0,10])
show() # colormap of the initial array

"""main loop"""

for i in range(n):
 for x in range(100):
  for y in range(100):
   T[x][y] += 0.1 # here i do some calculations, the details are not important

 # here I want to update the color map with the new array (T)

Thanks 谢谢

I would suggest using imshow ( doc ): 我建议使用imshowdoc ):

# figure set up
fig, ax_lst = plt.subplots(2, 1)
ax_lst = ax_lst.ravel()

#fake data
data = rand(512, 512)
x = np.linspace(0, 5, 512)
X, Y = meshgrid(x, x)

data2 = np.sin(X ** 2 + Y **2)
# plot the first time#fake data

im = ax_lst[0].imshow(data, interpolation='nearest', 
                            origin='bottom', 
                            aspect='auto', # get rid of this to have equal aspect
                            vmin=np.min(data),
                            vmax=np.max(data), 
                            cmap='jet')

cb = plt.colorbar(im)

pc = ax_lst[1].pcolor(data)
cb2 = plt.colorbar(pc)

To updata the data with imshow, just set the data array, and it takes care of all of the normalization and color mapping for you: 要使用imshow更新数据,只需设置数据数组,它即可为您处理所有规范化和颜色映射:

# update_data (imshow)
im.set_data(data2) 
plt.draw()

To do the same with thing with pcolor you need to do the normalization and color mapping your self (and guess the row-major vs column major right): 要对pcolor做同样的事情,您需要对自己进行归一化和颜色映射(并猜对行主要vs列主要是正确的):

my_cmap = plt.get_cmap('jet')
#my_nom = # you will need to scale your read data between [0, 1]
new_color = my_cmap(data2.T.ravel())
pc.update({'facecolors':new_color})

draw() 

You can connect events to your figure and call a specific function on that event. 您可以将事件连接到图形并在该事件上调用特定功能。 In the following I took an example of the matplotlib documentation and added a function ontype . 下面,我以matplotlib文档为例,并添加了一个ontype函数。 This is called when 1 is pressed on the keyboard. 在键盘上按1时将调用此选项。 Then X * func3() is called. 然后调用X * func3() Ontype is bound to the figure with fig.canvas.mpl_connect('key_press_event',ontype) . Ontype通过fig.canvas.mpl_connect('key_press_event',ontype)绑定到图形。 In a similar way you could fire regular events time dependent. 以类似的方式,您可以触发时间依赖的常规事件。

#!/usr/bin/env python
"""
See pcolor_demo2 for an alternative way of generating pcolor plots
using imshow that is likely faster for large grids
"""
from __future__ import division
from matplotlib.patches import Patch
from pylab import *

def ontype(event):
    ''' function that is called on key event (press '1')'''
    if event.key == '1':
        print 'It is working'
        fig.gca().clear()
        # plot new function X * func3(X, Y) 
        Z = X * func3(X, Y) 
        pcolor(X, Y, Z, cmap=cm.RdBu, vmax=abs(Z).max(), vmin=-abs(Z).max())
        fig.canvas.draw()

def func3(x,y):
    return (1- x/2 + x**5 + y**3)*exp(-x**2-y**2)


# make these smaller to increase the resolution
dx, dy = 0.05, 0.05

x = arange(-3.0, 3.0001, dx)
y = arange(-3.0, 3.0001, dy)
X,Y = meshgrid(x, y)

Z = func3(X, Y)

fig=figure(figsize=(16,8))

# connect ontype to canvas
fig.canvas.mpl_connect('key_press_event',ontype)

pcolor(X, Y, Z, cmap=cm.RdBu, vmax=abs(Z).max(), vmin=-abs(Z).max())
colorbar()
axis([-3,3,-3,3])

show()

I have here a simple example how to update ax.pcolor (or rather its faster cousin ax.pcolormesh ) during a simulation. 我在这里有一个简单的示例,该示例如何在仿真过程中更新ax.pcolor (或更确切地说,它是更快的表亲ax.pcolormesh )。

def make_movie(fig, meshData, conc, fout='writer_test.mp4',
           dpi=150, metadata={}):
    '''
    Make a movie (on disk) starting from a first image generated with matplotlib,
    by updating only the values that were dispayed with ax.pcolormesh(...).

    Parameters
    ----------
    meshData: mesh as returned by ax.pcolormesh()
    conc: obj returned by readUCN
        computed concentrations
    fout: str
        name of output file, with or without '.mp4' extension.
    dpi: int
        dots per inch of output movie
    metadata: dict
        passed on to FFMpegWriter.savings(fout, ...)
    '''
    plt.rcParams['animation.ffmpeg_path'] = '/usr/local/bin/ffmpeg'

    from matplotlib.animation import FFMpegWriter

    writer = FFMpegWriter(fps=15, metadata=metadata)

    totims = conc.totim # get times of computed concentrations

    with writer.saving(fig, fout, dpi):
        for totim in totims:
            C = conc.at_t(totim)[:, 0, :] # 3D -->  2D Xsection concentrations
            #newcolors = cmap(norm(C.ravel()))
            #meshData.update({'facecolors': newcolors})
            meshData.update({'array': C.ravel()}) # reset array to new conc.
            fig.canvas.draw_idle()
            writer.grab_frame()

The lines starting with #newcolors and #meshData.update are as suggested by @tacaswell above. #newcolors#meshData.update开头的行如上述#meshData.update所建议。 The line starting with meshdata.udate({array ... replaces them. It just updates the data without computing the new facecolors. The last method is simpler and works just as well. Transposing the data array is not necessary. meshdata.udate({array ...开头的行替换了它们。它只是更新数据而无需计算新的Facecolor。最后一种方法更简单且同样有效。不需要转置数据数组。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM