Python Matplotlib Basemap superposición imagen pequeña en el trazado del mapa

Estoy trazando datos de una aeronave en un mapa y me gustaría insertar esta imagen PNG de 75px por 29px de un avión en las coordenadas del último punto de datos en la gráfica.

avión http://sofes.miximages.com/python/mslr86.png

Por lo que sé y he leído, pyplot.imshow() es la mejor manera de lograr esto. Sin embargo, me estoy quedando colgado en el paso 1, obteniendo una imagen uniforme. Al usar una gráfica normal en lugar de un mapa base, es bastante fácil hacer que la imagen aparezca con imshow, pero cuando uso un mapa base, no puedo hacer que aparezca. Vea el código de ejemplo.

Si puedo obtener la imagen para mostrarla en el mapa, asumo que puedo, por prueba y error, establecer su posición y algunas dimensiones adecuadas para ella usando el atributo de extent de imshow() , con las coordenadas de la plot convertidas del mapa. Coordenadas x,y = m(lons,lats) .

Aquí está el código de ejemplo (para probarlo, es posible que desee descargar la imagen del avión arriba).

     from matplotlib import pyplot as plt from mpl_toolkits.basemap import Basemap import Image from numpy import arange lats = arange(26,29,0.5) lons = arange(-90,-87,0.5) m = Basemap(projection='cyl',llcrnrlon=min(lons)-2,llcrnrlat=min(lats)-2, urcrnrlon=max(lons)+2,urcrnrlat=max(lats)+2,resolution='i') x,y = m(lons,lats) u,v, = arange(0,51,10),arange(0,51,10) barbs = m.barbs(x,y,u,v) m.drawcoastlines(); m.drawcountries(); m.drawstates() img = Image.open('c130j_75px.png') im = plt.imshow(img, extent=(x[-1],x[-1]+50000,y[-1],y[-1]+50000)) plt.show() 

    Aquí está la imagen resultante, que no contiene un rastro del avión. He intentado varios tamaños diferentes utilizando la extent , pensando que podría haberlo hecho demasiado pequeño, pero sin éxito. También intenté configurar zorder=10 , pero también sin suerte. Cualquier ayuda sería apreciada.

    resultado http://sofes.miximages.com/python/35mgnev.png

    Actualización: ahora puedo hacer que la imagen aparezca al menos usando m.imshow lugar de plt.imshow , ya que la primera pasa en la instancia de los ejes del mapa, pero el argumento de la extent parece no tener efecto en las dimensiones de la imagen, como Siempre llena la ttwig completa, no importa cuán pequeña sea la dimensión de la extent , incluso si los pongo a cero. ¿Cómo puedo escalar adecuadamente la imagen del avión y colocarla cerca del último punto de datos?

    im = m.imshow(img, extent=(x[-1],x[-1]+5,y[-1],y[-1]+2))

    result2 http://sofes.miximages.com/python/2ntdy0o.png

    En realidad, para esto desea utilizar una función un tanto no documentada de matplotlib: el módulo matplotlib.offsetbox . Aquí hay un ejemplo: http://matplotlib.sourceforge.net/trunk-docs/examples/pylab_examples/demo_annotation_box.html

    En tu caso, harías algo como esto:

     import matplotlib.pyplot as plt import numpy as np import Image from mpl_toolkits.basemap import Basemap from matplotlib.offsetbox import OffsetImage, AnnotationBbox # Set up the basemap and plot the markers. lats = np.arange(26, 29, 0.5) lons = np.arange(-90, -87, 0.5) m = Basemap(projection='cyl', llcrnrlon=min(lons) - 2, llcrnrlat=min(lats) - 2, urcrnrlon=max(lons) + 2, urcrnrlat=max(lats) + 2, resolution='i') x,y = m(lons,lats) u,v, = np.arange(0,51,10), np.arange(0,51,10) barbs = m.barbs(x,y,u,v) m.drawcoastlines() m.drawcountries() m.drawstates() # Add the plane marker at the last point. plane = np.array(Image.open('plane.jpg')) im = OffsetImage(plane, zoom=1) ab = AnnotationBbox(im, (x[-1],y[-1]), xycoords='data', frameon=False) # Get the axes object from the basemap and add the AnnotationBbox artist m._check_ax().add_artist(ab) plt.show() 

    introduzca la descripción de la imagen aquí

    La ventaja de esto es que el plano está en coordenadas de ejes y se mantendrá del mismo tamaño en relación con el tamaño de la figura cuando se acerque.

    Con el mapa base, por lo general, solo puede usar los comandos normales del estilo de la pirota si primero traduce sus coordenadas utilizando la instancia del mapa. En este caso, puede simplemente transformar la extensión en coordenadas uv con:

     x0, y0 = m(x[-1], y[-1]) x1, y1 = m(x[-1] + 0.5, y[-1] + 0.5) 

    Y luego podrás hacer:

     im = plt.imshow(img, extent=(x0, x1, y0, y1)) 

    Mi solución completa a esto parece ser:

     import matplotlib.pyplot as plt from mpl_toolkits.basemap import Basemap import numpy as np lats = np.arange(26, 29, 0.5) lons = np.arange(-90, -87, 0.5) m = Basemap(projection='cyl', llcrnrlon=min(lons)-2, llcrnrlat=min(lats)-2, urcrnrlon=max(lons)+2, urcrnrlat=max(lats)+2, resolution='h') x, y = m(lons,lats) u, v = np.arange(0, 51, 10), np.arange(0, 51, 10) barbs = m.barbs(x, y, u, v) m.drawcoastlines() m.fillcontinents() x_size, y_size = 0.8, 0.4 x0, y0 = m(x[-1] - x_size/2., y[-1] - y_size/2.) x1, y1 = m(x[-1] + x_size/2., y[-1] + y_size/2.) im = plt.imshow(plt.imread('mslr86.png'), extent=(x0, x1, y0, y1)) plt.show() 

    Lo que produce una imagen que parece introduzca la descripción de la imagen aquí

    Actualización: si desea que la imagen siga siendo un tamaño fijo, independientemente del zoom, vea la respuesta de Joe.