如何使用Matplotlib可视化标量2D数据?

时间:2011-02-26 15:10:28

标签: python matplotlib

所以我有一个meshgrid(矩阵X和Y)以及标量数据(矩阵Z),我需要将其可视化。优选地,一些2D图像在其中显示Z值的点处具有颜色。 我做了一些研究,但没有发现任何我想要的东西。

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

pyplot.pcolor(X,Y,Z)使彩色方块的颜色与其一个角上的数据相对应,因此它会错误地表示数据(它应该在其中心显示数据或其他内容)。此外,它忽略了数据矩阵中的两条边。

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

4 个答案:

答案 0 :(得分: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()

答案 1 :(得分:2)

如果你的meshgrid具有统一的间距,你可以继续使用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')

或保罗建议,使用其中一个轮廓函数

答案 2 :(得分: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,a.k.a。backend = TkAgg

感谢您对所有事情的帮助。

答案 3 :(得分: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