问题
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