Pregunta

estoy mirando el proyección personalizada Ejemplo en la galería matplotlib. Estoy intentando modificarlo para trazar solo el hemisferio sur.He ajustado los límites necesarios [-pi/2,pi/2] a [-pi/2,0].Ahora he estado mirando:

def _gen_axes_patch(self):
    """
    Override this method to define the shape that is used for the
    background of the plot.  It should be a subclass of Patch.

    In this case, it is a Circle (that may be warped by the axes
    transform into an ellipse).  Any data and gridlines will be
    clipped to this shape.
    """
    #return Circle((0.5, 0.5), 0.5)
    return Wedge((0.5,0.5), 0.5, 180, 360)

def _gen_axes_spines(self):
    return {'custom_hammer':mspines.Spine.circular_spine(self,
                                                  (0.5, 0.5), 0.25)}

Como puedes ver, reemplacé el parche Circle con un Wedge.Así es como se ve actualmente el gráfico de proyección:projection plot

El lomo sigue el círculo/elipse. ¿Cómo puedo especificar que quiero que el lomo siga el límite de la cuña?

No estoy seguro de cuál es la mejor manera de modificar la columna, por lo que cualquier ayuda sería muy apreciada.

Gracias,

Alex

¿Fue útil?

Solución

Solo para que conste, definitivamente estás saltando directamente al fondo de la piscina si todavía eres nuevo en Python.(¡Y felicitaciones por entrar directamente!)

Lo que estás haciendo requiere un conocimiento razonablemente detallado del funcionamiento interno de matplotlib, que es una biblioteca bastante compleja.

Dicho esto, ¡es una buena manera de aprender rápidamente!

Para algo como esto, es necesario entender el interno arquitectura de cómo se estructuran las cosas en lugar de solo la API "pública".

Para la mayor parte de esto, debes profundizar y "usar la fuente".Para cualquier proyecto, la documentación del funcionamiento interno es el código mismo.

Dicho esto, para un caso simple, es bastante sencillo.

import numpy as np
from matplotlib.projections.geo import HammerAxes
import matplotlib.projections as mprojections
from matplotlib.axes import Axes
from matplotlib.patches import Wedge
import matplotlib.spines as mspines

class LowerHammerAxes(HammerAxes):
    name = 'lower_hammer'
    def cla(self):
        HammerAxes.cla(self)
        Axes.set_xlim(self, -np.pi, np.pi)
        Axes.set_ylim(self, -np.pi / 2.0, 0)

    def _gen_axes_patch(self):
        return Wedge((0.5, 0.5), 0.5, 180, 360)

    def _gen_axes_spines(self):
        path = Wedge((0, 0), 1.0, 180, 360).get_path()
        spine = mspines.Spine(self, 'circle', path)
        spine.set_patch_circle((0.5, 0.5), 0.5)
        return {'wedge':spine}

mprojections.register_projection(LowerHammerAxes)

if __name__ == '__main__':
    import matplotlib.pyplot as plt
    fig = plt.figure()
    ax = fig.add_subplot(111, projection='lower_hammer')
    ax.grid(True)
    plt.show()

enter image description here

Profundicemos en el _get_axes_spines método un poco:

def _gen_axes_spines(self):
    """Return the spines for the axes."""
    # Make the path for the spines
    # We need the path, rather than the patch, thus the "get_path()"
    # The path is expected to be centered at 0,0, with radius of 1
    # It will be transformed by `Spine` when we initialize it
    path = Wedge((0, 0), 1.0, 180, 360).get_path()

    # We can fake a "wedge" spine without subclassing `Spine` by initializing 
    # it as a circular spine with the wedge path. 
    spine = mspines.Spine(self, 'circle', path)

    # This sets some attributes of the patch object. In this particular 
    # case, what it sets happens to be approriate for our "wedge spine"
    spine.set_patch_circle((0.5, 0.5), 0.5)

    # Spines in matplotlib are handled in a dict (normally, you'd have top,
    # left, right, and bottom, instead of just wedge). The name is arbitrary
    return {'wedge':spine}

Ahora hay algunos problemas con esto:

  1. Las cosas no están centradas correctamente dentro del eje.
  2. El parche de los ejes podría ampliarse un poco más para ocupar adecuadamente el espacio dentro de los ejes.
  3. Estamos dibujando las líneas de la cuadrícula para el globo completo y luego recortándolas.Sería más eficiente atraerlos únicamente dentro de nuestra cuña "inferior".

Sin embargo, cuando echamos un vistazo a cómo HammerAxes está estructurado, notarás que muchas de estas cosas (especialmente el centrado del parche del eje) están efectivamente codificadas en las transformaciones.(Como mencionan en los comentarios, está destinado a ser un ejemplo de "juguete", y asumir que siempre estás tratando con el globo completo hace que las matemáticas en las transformaciones sean mucho más simples).

Si desea solucionar estos problemas, deberá modificar varias de las diversas transformaciones en HammerAxes._set_lim_and_transforms.

Sin embargo, funciona razonablemente bien tal como está, así que lo dejaré como ejercicio para el lector.:) (Tenga en cuenta que esa parte es un poco más difícil, ya que requiere un conocimiento detallado de las transformaciones de matplotlib).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top