【问题标题】:Non-linear axes for imshow in matplotlibmatplotlib 中 imshow 的非线性轴
【发布时间】:2019-08-20 01:40:35
【问题描述】:

我正在对数坐标轴上生成二维数组(例如,x 像素坐标是使用 logspace(log10(0.95), log10(2.08), n) 生成的。

我想使用普通的旧 imshow 以原始分辨率和缩放比例显示图像(我不需要 to stretch it;数据本身已经对数缩放),但我想添加刻度、标签、线条位于对数轴上的正确位置。我该怎么做?

理想情况下,我可以只使用命令行axvline(1.5),并且该行将位于正确的位置(距左侧 58%),但如果唯一的方法是在对数坐标和图像坐标之间手动转换,那也没关系.

对于线性轴,在对 imshow 的调用中使用 extents= 可以满足我的要求,但我没有看到用对数轴做同样事情的方法。

例子:

from matplotlib.colors import LogNorm

x = logspace(log10(10), log10(1000), 5)
imshow(vstack((x,x)), extent=[10, 1000, 0, 100], cmap='gray', norm=LogNorm(), interpolation='nearest')
axvline(100, color='red')

这个例子不起作用,因为extent=只适用于线性刻度,所以在100处做axvline时,它不会出现在中心。我希望 x 轴显示 10、100、1000 和 axvline(100),以便在 100 点的中心放置一条线,同时像素保持等距。

【问题讨论】:

  • 您能否提供一些您想要实现的工作代码或图像。另一个问题是您是否灵活地使用 pcolor 代替 imshow。
  • @imsc:添加了一个示例。我认为 pcolor 很好。

标签: image plot matplotlib logarithm


【解决方案1】:

在我看来,最好使用pcolor 和常规(未转换)x 和y 值。 pcolor 为您提供更大的灵活性,并且常规的 x 和 y 轴更容易混淆。

import pylab as plt
import numpy as np
from matplotlib.colors import LogNorm
from matplotlib.ticker import LogFormatterMathtext

x=np.logspace(1, 3, 6)
y=np.logspace(0, 2,3)
X,Y=np.meshgrid(x,y)
z = np.logspace(np.log10(10), np.log10(1000), 5)
Z=np.vstack((z,z))

im = plt.pcolor(X,Y,Z, cmap='gray', norm=LogNorm())
plt.axvline(100, color='red')

plt.xscale('log')
plt.yscale('log')

plt.colorbar(im, orientation='horizontal',format=LogFormatterMathtext())
plt.show()

由于pcolor 很慢,因此更快的解决方案是使用pcolormesh。

im = plt.pcolormesh(X,Y,Z, cmap='gray', norm=LogNorm())

【讨论】:

  • 这看起来可以解决我的问题。这是一个更简单的示例,可以解决我试图解决的问题:gist.github.com/3124528 所以 pcolor 就像一个非常慢的 imshow ,它将每个像素绘制为一个矩形?没有办法用 imshow 做xscale('log')?
  • pcolormesh 看起来是一种更快的方法来做同样的事情。 “pcolormesh 使用 QuadMesh,一种更快的 pcolor 泛化,但有一些限制。”不确定这些限制是什么,但它似乎有效。
  • pcolormesh 似乎是一个不错的选择。限制之一是它不能与掩码坐标数组一起使用。
  • 不幸的是,与 imshow 相比,这会导致结果图像中的插值错误,imshow 可以很好地进行插值。 :/ waiiiiit 等一下.....我刚刚尝试了 imshow 的范围,然后是 xscale('log'),它工作正常。
  • 您能否将您的解决方案作为新答案。
【解决方案2】:

实际上,它工作正常。我很困惑。

以前我收到关于“非线性轴不支持图像”的错误,这就是我问这个问题的原因。但是现在当我尝试它时,它可以工作:

import matplotlib.pyplot as plt
import numpy as np

x = np.logspace(1, 3, 5)
y = np.linspace(0, 2, 3)
z = np.linspace(0, 1, 4)
Z = np.vstack((z, z))

plt.imshow(Z, extent=[10, 1000, 0, 1], cmap='gray')
plt.xscale('log')

plt.axvline(100, color='red')

plt.show()

这比pcolor() 和pcolormesh() 更好,因为

  1. 它不是非常慢而且
  2. 当图像未以原始分辨率显示时,插值效果很好,不会产生误导性伪影。

【讨论】:

  • 我同样感到困惑。以前,我用log 尝试过imshow,但没有成功,但现在可以正常工作了。
  • 我们发现,如果您删除 extent,它将无法正常工作。也就是说,plt.imshow(Z,cmap='gray'); plt.xscale('log') 会引发错误。
  • @developer 哦,可能是因为默认范围从 0 开始?
  • 这在 MPL2 中停止工作了吗? ...大概:matplotlib.org/devdocs/users/…
  • 这还能用吗?我没有得到任何错误,但图像被对数比例拉伸和变形。就像我希望所有的正方形都具有相同的大小,但事实并非如此。
猜你喜欢
  • 2016-03-04
  • 2020-04-08
  • 2010-12-13
  • 1970-01-01
  • 2017-12-28
  • 2012-09-07
  • 1970-01-01
  • 2013-08-16
  • 2012-09-01
相关资源
最近更新 更多