简体   繁体   English

使图像输入适合绘图中的范围-Python

[英]Fits image input to a range in plot - Python

I'm wondering if I could "scale" a image input to be plotted to a range in the plot. 我想知道是否可以“缩放”要绘制的图像输入到绘图范围内。 To be more clear, this is what I need: 更清楚地说,这就是我需要的:

I have a 400 * 400 image that is generated based on a function which interval is -1..1. 我有一个基于间隔为-1..1的函数生成的400 * 400图像。 So, I do a translate to save this data, like this: 因此,我进行了翻译以保存此数据,如下所示:

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)

Ie, first I map its position to my range and then I calculate de f(x, y) based on this "new position" and save the data. 即,首先我将其位置映射到我的范围,然后根据此“新位置”计算de f(x,y)并保存数据。

The problem is that, later, I have to represent the image contour in the function range. 问题是,稍后,我必须在功能范围内表示图像轮廓。 So, I have an image, 400 * 400, that I have to represent in a plot which range is -1..1. 因此,我有一张400 * 400的图像,必须在范围为-1..1的图中表示。

This works pretty well: 这很好用:

import pylab as plt

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

But I couldn't find a way to have the x/y axes in the range -1..1 但是我找不到将x / y轴设置在-1..1范围内的方法

I tried this: 我尝试了这个:

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)

But it doesn't works, and it makes senses to not work, but I don't know how could I do what I want. 但这是行不通的,不行是有道理的,但是我不知道该怎么做。 I have the information about the data in this image, so I also tried to do something like these two approaches: 我在此图像中具有有关数据的信息,因此我也尝试执行以下两种方法:

# 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)

Which don't work either. 哪个也不起作用。

Any help would be much appreciated. 任何帮助将非常感激。 Thanks. 谢谢。

You can do this simpily using the extent kwarg: 您可以使用extent kwarg简单地执行此操作:

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

( doc ) It will also work with contour , contourf ect. doc )也可用于contourcontour contourf

for example: 例如:

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

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

在此处输入图片说明

An alternate way to deal with this is, if you really don't want to use extent and make your life easier is to hi-jack the formatter to insert a scaling factor: 对付这种情况的另一种方法是,如果你真的不想使用extent ,使您的生活更轻松是hi-jack位置插入一个缩放因子格式:

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)

在此处输入图片说明

I actually wrote a code to do something similar myself because it has implications for a lot of science apps. 我实际上写了一个代码来自己做类似的事情,因为它对很多科学应用程序都有影响。 I happened to be tweaking that code while checking stackoverflow for something else, so it's your lucky day.... below is a function that plots an image with appropriate tick marks on the axes. 我碰巧在检查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)

This would plot an image, it would be fairly trivial for you then to use contour(im) after running this function to overlay contours on to a properly axisified map, although you have to be careful about the axis to make sure they're flipped in the ways that you want them.... 这将绘制图像,对于您而言,在运行此功能以将等高线叠加到正确的轴化地图上之后,然后使用contour(im)相当简单,尽管您必须注意轴以确保将其翻转以您想要的方式...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM