【问题标题】:Fits image input to a range in plot - Python使图像输入适合绘图中的范围 - Python
【发布时间】:2013-09-14 04:40:16
【问题描述】:

我想知道是否可以“缩放”要绘制到绘图范围内的图像输入。 更清楚地说,这就是我需要的:

我有一个 400 * 400 的图像,它是基于间隔为 -1..1 的函数生成的。所以,我做了一个翻译来保存这些数据,像这样:

x = Utils.translate(pos_x, 0, self.width, -1, 1)
y = Utils.translate(pos_y, 0, self.height, -1, 1)
data = Utils.map_position_to_function(x, y)

即,首先我将其位置映射到我的范围,然后根据这个“新位置”计算 de f(x, y) 并保存数据。

问题是,后来,我必须在函数范围内表示图像轮廓。 所以,我有一个图像,400 * 400,我必须在一个范围为 -1..1 的图中表示。

这很好用:

import pylab as plt

im = plt.array(Image.open('Mean.png').convert('L'))
plt.figure()
plt.contour(im, origin='image')
plt.axis('equal')

但我找不到让 x/y 轴在 -1..1 范围内的方法

我试过了:

row = np.linspace(-1,1,0.25)
X,Y = np.meshgrid(row,row)
Z = plt.array(Image.open('Mean.png').convert('L'))
plt.contour(X,Y,Z)

但它不起作用,不起作用是有意义的,但我不知道我该怎么做我想要的。我有关于这张图片中数据的信息,所以我也尝试做类似这两种方法的事情:

# 1
plt.figure()
row = np.linspace(-1,1,0.25)
X,Y = np.meshgrid(row,row)
Z = ImageMedia[Utils.translate(X, 400, 400, -1, 1), Utils.translate(Y, 400, 400, -1, 1)]
plt.contour(X,Y,Z)

# 2
im = plt.array(Image.open('Mean.png').convert('L'))
plt.figure()
plt.contour(im, origin='image')
v = [-1, 1, -1, 1]
plt.axis(v)

这也不起作用。

任何帮助将不胜感激。 谢谢。

【问题讨论】:

  • 你用错了linspace,是linspace(min, max, number_of_steps)
  • 谢谢。我不知道。 (:

标签: python matplotlib axis


【解决方案1】:

您可以使用extent kwarg 简单地做到这一点:

im = ax.imshow(data, ..., extent=[-1, 1, -1, 1])

(doc) 它也适用于contourcontourf 等。

例如:

fig, ax2 = plt.subplots(1, 1)

im = rand(400, 400)
ax2.imshow(im, interpolation='none', extent=[-1, 1, -1, 1])

解决此问题的另一种方法是,如果您真的不想使用 extent 并让您的生活更轻松,请劫持格式化程序以插入比例因子:

from matplotlib.ticker import FuncFormatter

fig, ax2 = plt.subplots(1, 1)

im = rand(400, 400)
ax2.imshow(im, interpolation='none', origin='bottom')

nbins = 5
scale_factor = .5
form_fun = lambda x, i, scale_factor=scale_factor: '{:.3f}'.format(scale_factor * x)
ax2.get_xaxis().set_major_formatter(FuncFormatter(form_fun))
ax2.get_yaxis().set_major_formatter(FuncFormatter(form_fun))
ax2.get_xaxis().get_major_locator().set_params(nbins=nbins)
ax2.get_yaxis().get_major_locator().set_params(nbins=nbins)

【讨论】:

  • 是的,我想我太菜鸟了,我不知道如何在我的代码中使用它。最后,我还带着最后一个疑问编辑了我的问题。你能读出来吗? (:非常感谢!
  • 如果您还有其他问题,请打开一个新问题。
  • 现在我明白你的意思了!谢谢!
  • 嗨,@tcaswell。很抱歉回到这里,但我提出了另一个类似的问题 (stackoverflow.com/questions/18817110/…),而且,同样,我虽然你可以知道答案......谢谢。
【解决方案2】:

实际上,我自己编写了一个代码来做类似的事情,因为它对许多科学应用程序都有影响。我碰巧在检查 stackoverflow 的其他内容时调整了该代码,所以今天是你的幸运日......下面是一个函数,它在轴上绘制带有适当刻度线的图像。

def plotmap(mapx, mapy, mymap,flipx=False, nt=4):
   '''plots a map (mymap) with specified axes (mapx, mapy) and number of ticks (nt)'''
   nx=len(mapx)
   ny=len(mapy)

   mymap=mymap[:,::-1] #flip y axis (make start from lower left, rather than upper)
   if(flipx): #flip x-axis (useful in some applications (e.g. west longitude))
     mymap=mymap[::-1,:]

   pl.imshow(mymap.transpose()) #plot an image map.. but contour could work too
   pl.colorbar()
   if(flipx):
     mapx=mapx[::-1]
   myxticks=pl.arange(mapx[0],mapx[-1], (mapx[-1]-mapx[0])/nt) #picks appropriate tick marks
   myyticks=pl.arange(mapy[-1],mapy[0], -(mapy[-1]-mapy[0])/nt)
   for i in range(nt):
     myxticks[i]=round(myxticks[i],3) #makes the ticks pretty by lopping off insignificant figures
     myyticks[i]=round(myyticks[i],3)
   pl.xticks(range(0, nx, nx/nt), myxticks) #plots ticks at corresponding coordinates
   pl.yticks(range(0, ny, ny/nt), myyticks)

这将绘制图像,然后在运行此函数后使用contour(im) 将轮廓覆盖到正确轴化的地图上对您来说是相当简单的,尽管您必须小心轴以确保它们'以你想要的方式重新翻转......

【讨论】:

  • 呸,你在重新发明轮子!
  • origin kwarg 翻转图像。你真的应该使用FormatterLocator 类来设置刻度位置。为您做所有的工作。
  • 它是一个更大的代码的一部分,可以做更多的事情,但感谢您对问题和 cmets 的回答。我不知道这些参数....范围会有所帮助(起源较少,仍然需要转置以使图像像我想要的那样工作)。
  • 另外,您的方法会产生不同的结果,其中图像变为范围 x 范围而不是按索引进行索引,这可能是也可能不是人们想要的。
  • 我不明白您所说的索引 x 索引是什么意思。像素中心的位置有一些微妙之处,但可以通过适当的 +/- delta 在您的限制上进行修复(范围是 边缘 的位置而不是中心)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-26
  • 1970-01-01
  • 1970-01-01
  • 2021-11-24
  • 2013-09-19
相关资源
最近更新 更多