【问题标题】:Python: 2D color map with imshowPython:带有 imshow 的 2D 颜色图
【发布时间】:2014-07-22 20:56:22
【问题描述】:

我正在尝试使用颜色在二维图上表示两个变量的函数。 我遇到了这个例子here

from numpy import exp,arange
from pylab import meshgrid,cm,imshow,contour,clabel,colorbar,axis,title,show
# the function that I'm going to plot
def z_func(x,y):
 return (1-(x**2+y**3))*exp(-(x**2+y**2)/2)

x = arange(-3.0,3.0,0.1)
y = arange(-3.0,3.0,0.1)
X,Y = meshgrid(x, y) # grid of point
Z = z_func(X, Y) # evaluation of the function on the grid

im = imshow(Z,cmap=cm.RdBu) # drawing the function
# adding the Contour lines with labels
cset = contour(Z,arange(-1,1.5,0.2),linewidths=2,cmap=cm.Set2)
clabel(cset,inline=True,fmt='%1.1f',fontsize=10)
colorbar(im) # adding the colobar on the right
# latex fashion title
title('$z=(1-x^2+y^3) e^{-(x^2+y^2)/2}$')
show()

产生

但是,轴的刻度和范围与实际的 x 和 y 数据不对应(两者都在 -3 和 3 之间)。如何让它们与实际数据对应?

【问题讨论】:

标签: python graphics graph matplotlib


【解决方案1】:

我不会使用 imshow 来绘制二维函数,imshow 用于显示图像。

轴标签来自“像素”的数量。你的价值观。

要绘制二维函数,请使用plt.pcolormesh

这需要一个像素网格,您应该在该网格的中心评估您的函数。这将产生锐利的像素:

import numpy as np
import matplotlib.pyplot as plt


def z_func(x, y):
    return (1 - (x ** 2 + y ** 3)) * np.exp(-(x ** 2 + y ** 2) / 2)

x = np.arange(-3.0, 3.0, 0.1)
y = np.arange(-3.0, 3.0, 0.1)
x_center = 0.5 * (x[:-1] + x[1:])
y_center = 0.5 * (y[:-1] + y[1:])

X, Y = np.meshgrid(x_center, y_center)
Z = z_func(X, Y)

# pcolormesh needs the pixel edges for x and y
# and with default flat shading, Z needs to be evaluated at the pixel center
plot = plt.pcolormesh(x, y, Z, cmap='RdBu', shading='flat')

# contour needs the centers
cset = plt.contour(X, Y, Z, cmap='gray')
plt.clabel(cset, inline=True)

plt.colorbar(plot)
plt.savefig('plot_z_flat.png')


您也可以使用 gouraud 着色来获得平滑的图像,但是您必须像这样评估边缘的功能:


import numpy as np
import matplotlib.pyplot as plt


def z_func(x, y):
    return (1 - (x ** 2 + y ** 3)) * np.exp(-(x ** 2 + y ** 2) / 2)

x = np.arange(-3.0, 3.0, 0.1)
y = np.arange(-3.0, 3.0, 0.1)

X, Y = np.meshgrid(x, y)
Z = z_func(X, Y)

# pcolormesh needs the pixel vertices for x and y
# and with gouroud shading, Z has to be evaluated on all vertices
plot = plt.pcolormesh(X, Y, Z, cmap='RdBu', shading='gouraud')

# countour needs the center points
x_center = 0.5 * (x[:-1] + x[1:])
y_center = 0.5 * (y[:-1] + y[1:])
X, Y = np.meshgrid(x, y)
Z = z_func(X, Y)

cset = plt.contour(X, Y, Z, cmap='gray')
plt.clabel(cset, inline=True)

plt.colorbar(plot)
plt.show()

【讨论】:

  • 你好,很久没有回复了,但你也知道如何在绘图本身旁边添加一个表示颜色->值映射的垂直颜色条吗? pcolor 对我有用,但我找不到如何添加颜色栏列。谢谢
  • 通过无花果设法做到了,ax = plt.subplots()pos = ax.pcolor(xlocs, ylocs, Efieldvalues.T, cmap="RdBu")fig.colorbar(pos, ax=ax)
  • 我用两个当前最好的解决方案更新了答案;)
【解决方案2】:

在对imshow 的调用中添加extent=(-3, 3, 3, -3)extent=(-3, 3, -3, 3)(请注意标志的不幸变化!)拨打contour

import numpy as np
import matplotlib.pyplot as plt


def z_func(x, y):
    return (1 - (x ** 2 + y ** 3)) * np.exp(-(x ** 2 + y ** 2) / 2)

x = np.arange(-3.0, 3.0, 0.1)
y = np.arange(-3.0, 3.0, 0.1)
X, Y = np.meshgrid(x, y)
Z = z_func(X, Y) 


im = plt.imshow(Z, cmap=plt.cm.RdBu, extent=(-3, 3, 3, -3))  
cset = plt.contour(Z, np.arange(-1, 1.5, 0.2), linewidths=2,
                   cmap=plt.cm.Set2,
                   extent=(-3, 3, -3, 3))
plt.clabel(cset, inline=True, fmt='%1.1f', fontsize=10)
plt.colorbar(im)  

plt.title('$z=(1-x^2+y^3) e^{-(x^2+y^2)/2}$')

plt.show()

【讨论】:

  • 要和imshow一致你要extent=(-3,3,3,-3)
  • 等高线颠倒了。轮廓的“范围”应为 (-3,3,-3,3),与 imshow 相反。
【解决方案3】:

颜色条轴的范围由Z 的最小值和最大值决定。

>>> Z.min()
-0.96365584108555036

>>> Z.max()
1.4203545446927801

默认情况下,图上 x 和 y 轴的范围是数组 Z 中的索引。正如 Warren 指出的那样,您可以使用 extent 关键字参数更改坐标轴的标记方式 imshow

extent = (-3.0,3.0, 3.0,-3.0)

或更一般地

extent = (x[0],x[-1], y[-1],y[0] )
imshow( Z,cmap=cm.RdBu, extent=extent )
cset = contour(Z,arange(-1,1.5,0.2),linewidths=2,cmap=cm.Set2,extent=extent)

extent 采用低 x 坐标,然后是高 x,然后是低 y,然后是高 y。图像的默认约定是 y 轴的原点从左上角开始。这就是为什么extent 中的最后两个条目与您的预期“相反”。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-07-08
    • 2021-07-19
    • 2018-01-23
    • 2021-06-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多