2011-02-26 23 views
10

所以我有一个meshgrid(矩阵X和Y)与标量数据(矩阵Z),我需要可视化这个。优选地,在点处具有颜色的一些2D图像显示Z的值。 我已经做了一些研究,但没有找到任何正是我想要的。如何使用Matplotlib可视化标量2D数据?

pyplot.imshow(Z)有一个很好的外观,但它不需要我的X和Y矩阵,所以轴是错误的,它不能处理由X和Y给出的非线性间隔点。

pyplot.pcolor(X,Y,Z)使得彩色正方形的颜色对应于其中一个角落处的数据,因此它会错误地表示数据(它应该在其中心显示数据)。另外,它忽略数据矩阵中的两条边。

我非常确定在Matplotlib中必须存在一些更好的方法,但是文档使得很难获得概述。所以我问,如果别人知道更好的方法。如果它允许我刷新矩阵Z以制作动画,则为奖励。

回答

9

这看起来不错,但效率很低:

from pylab import * 
origin = 'lower' 

delta = 0.025 

x = y = arange(-3.0, 3.01, delta) 
X, Y = meshgrid(x, y) 
Z1 = bivariate_normal(X, Y, 1.0, 1.0, 0.0, 0.0) 
Z2 = bivariate_normal(X, Y, 1.5, 0.5, 1, 1) 
Z = 10 * (Z1 - Z2) 

nr, nc = Z.shape 

CS = contourf(
    X, Y, Z, 
    levels = linspace(Z.min(), Z.max(), len(x)), 
    ls = '-', 
    cmap=cm.bone, 
    origin=origin) 

CS1 = contour(
    CS, 
    levels = linspace(Z.min(), Z.max(), len(x)), 
    ls = '-', 
    cmap=cm.bone, 
    origin=origin) 

show() 

这是我,我会重新插入(使用scipy.interpolate)数据到一个规则的网格和使用imshow(),设置范围来修复轴。 (每评论)

fine contour

编辑:

动画轮廓图,可以这样来完成,但是,就像我说的,上面是等高线图功能的低效只是普通的滥用。做你想做的最有效的方法是使用SciPy。你有没有安装?

import matplotlib 
matplotlib.use('TkAgg') # do this before importing pylab 
import time 
import matplotlib.pyplot as plt 

fig = plt.figure() 
ax = fig.add_subplot(111) 

def animate(): 
    origin = 'lower' 
    delta = 0.025 

    x = y = arange(-3.0, 3.01, delta) 
    X, Y = meshgrid(x, y) 
    Z1 = bivariate_normal(X, Y, 1.0, 1.0, 0.0, 0.0) 
    Z2 = bivariate_normal(X, Y, 1.5, 0.5, 1, 1) 
    Z = 10 * (Z1 - Z2) 

    CS1 = ax.contourf(
     X, Y, Z, 
     levels = linspace(Z.min(), Z.max(), 10), 
     cmap=cm.bone, 
     origin=origin) 

    for i in range(10): 
     tempCS1 = contourf(
      X, Y, Z, 
      levels = linspace(Z.min(), Z.max(), 10), 
      cmap=cm.bone, 
      origin=origin) 
     del tempCS1 
     fig.canvas.draw() 
     time.sleep(0.1) 
     Z += x/10 

win = fig.canvas.manager.window 
fig.canvas.manager.window.after(100, animate) 
plt.show() 
+0

感谢。是否有可能更新此CS对象中的数据,以便我可以在循环中制作某种动画? – Eskil 2011-02-26 16:57:46

+0

@Eskil:查看我的更新。 – Paul 2011-02-26 18:17:51

+0

是的,我有Scipy。但我认为Scipy使用Matplotlib进行所有绘图。它也有自己独立的绘图功能吗? – Eskil 2011-02-27 22:37:23

2

如果您的网格网格具有均匀的间距,您可以继续使用pcolor,但只是为了将数据集中在特定值而非拐角处而将X和Y移位。

你也可以用散点图,明确将一些大小的点,在准确的X和Y点,然后设置颜色为Z:

x = numpy.arange(10) 
y = numpy.arange(10) 
X,Y = numpy.meshgrid(x,y) 
Z = numpy.arange(100).reshape((10,10)) 
scatter(X,Y,c=Z,marker='s',s=1500) 
#I picked a marker size that basically overlapped the symbols at the edges 
axis('equal') 

或:

pcolor(X+0.5,Y+0.5,Z) 
axis('equal') 

或正如Paul建议的那样,使用轮廓函数之一

1

如果有人遇到这篇文章找什么,我一直在寻找,我把上面的例子中,并修改它使用imshow与帧的输入堆栈,而不是产生和使用的飞行轮廓。从形状(nBins,nBins,nBins)的3D图像开始,称为frames

def animate_frames(frames): 
    nBins = frames.shape[0] 
    frame = frames[0] 
    tempCS1 = plt.imshow(frame, cmap=plt.cm.gray) 
    for k in range(nBins): 
     frame = frames[k] 
     tempCS1 = plt.imshow(frame, cmap=plt.cm.gray) 
     del tempCS1 
     fig.canvas.draw() 
     #time.sleep(1e-2) #unnecessary, but useful 
     fig.clf() 

fig = plt.figure() 
ax = fig.add_subplot(111) 

win = fig.canvas.manager.window 
fig.canvas.manager.window.after(100, animate_frames, frames) 

我还发现了一个更简单的方法去了解这整个过程中,尽管不那么稳健:

fig = plt.figure() 

for k in range(nBins): 
    plt.clf() 
    plt.imshow(frames[k],cmap=plt.cm.gray) 
    fig.canvas.draw() 
    time.sleep(1e-6) #unnecessary, but useful 

注意,这两个似乎只与ipython --pylab=tk,又名工作backend = TkAgg

谢谢你的帮助。

0

以下函数在边界处创建一半大小的框(如附图所示)。

import matplotlib.pyplot as plt 
import numpy as np 
from scipy.ndimage.filters import convolve 

def pcolor_all(X, Y, C, **kwargs): 
    X = np.concatenate([X[0:1,:], X], axis=0) 
    X = np.concatenate([X[:,0:1], X], axis=1) 

    Y = np.concatenate([Y[0:1,:], Y], axis=0) 
    Y = np.concatenate([Y[:,0:1], Y], axis=1) 

    X = convolve(X, [[1,1],[1,1]])/4 
    Y = convolve(Y, [[1,1],[1,1]])/4 

    plt.pcolor(X, Y, C, **kwargs) 

X, Y = np.meshgrid(
    [-1,-0.5,0,0.5,1], 
    [-2,-1,0,1,2]) 

C = X**2-Y**2 

plt.figure(figsize=(4,4)) 

pcolor_all(X, Y, C, cmap='gray') 

plt.savefig('plot.png') 

plot.png