Fits image input to a range in plot - Python

老子叫甜甜 提交于 2019-12-11 08:56:09

问题


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

I.e, 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.

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.

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

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.


回答1:


You can do this simpily using the extent kwarg:

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

(doc) It will also work with contour, contourf ect.

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:

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)




回答2:


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.

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....



来源:https://stackoverflow.com/questions/18792624/fits-image-input-to-a-range-in-plot-python

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!