ajuste_text's only_move parámetro not working for overlapping last value outside of the plot area?

He estado tratando de usar el adjustText biblioteca para ajustar dos anotación de trama que se superponen entre sí. Estoy haciendo algo así:

import matplotlib
import matplotlib.pyplot as plt
from adjustText import adjust_text
import numpy as np

foo = np.linspace(1, 100,  1000)
bar = np.linspace(1, 100.1, 1000)
x = np.linspace(0,1,1000)

w, h = plt.figaspect(9/16) 
fig = plt.figure(figsize=(w, h), dpi=300, frameon=False)
ax = plt.gca()

plt.xlim(x[0], x[-1])

ax.plot(x, foo, label='Foo', color='b')
plt.annotate(f'{foo[-1]}',
         xy = (1, foo[-1]),
         xytext=(8, 0), 
         xycoords=('axes fraction', 'data'),
         textcoords='offset points',
         color='b'
        )

ax.plot(x, bar, label='Bar', color='orange')
plt.annotate(f'{bar[-1]}',
         xy = (1, bar[-1]),
         xytext=(8, 0), 
         xycoords=('axes fraction', 'data'),
         textcoords='offset points',
         color='orange'
        )

Que resulta en una figura con anotaciones superpuestas

Overlapping annotations

Entonces intenté usar el adjust_text función y añade las siguientes líneas de código al bloque original:

annotations = [child for child in ax.get_children() if isinstance(child, matplotlib.text.Annotation)]
adjust_text(annotations,
            only_move={'points':'xy', 'text':'y', 'objects':'xy'},
            autoalign='y',
           )

Y luego los textos dejaron de sobreponerse entre sí, pero comenzaron a superponerse con las líneas de la trama. ¿Qué estoy haciendo mal?

New image

Pregunta hecha hace 3 años, 4 meses, 28 días - Por pixelprodigy50bb


3 Respuestas:

  • No estoy familiarizado con la biblioteca AjusteText, así que he probado varios parámetros y no he conseguido los resultados esperados. Sin embargo, Autoalign='y' tuvo un efecto. Luego reajusté la posición en el lado matplotlib.

    ax.plot(x, foo, label='Foo', color='b')
    plt.annotate(f'{foo[-1]}',
             xy = (1, foo[-1]),
             xytext=(20, 0), 
             xycoords=('axes fraction','data'),
             textcoords='offset points',
             color='b'
            )
    
    ax.plot(x, bar, label='Bar', color='orange')
    plt.annotate(f'{bar[-1]}',
             xy = (1, bar[-1]),
             xytext=(20, 0), 
             xycoords=('axes fraction','data'),
             textcoords='offset points',
             color='orange'
            )
    
    annotations = [child for child in ax.get_children() if isinstance(child, matplotlib.text.Annotation)]
    adjust_text(annotations,
                autoalign='y'
               )
    

    enter image description here

    Respondida el Dec 18, 2020 a las 14:25 - por debugdynamo

    Votos positivos: 0 | Votos negativos: 0

  • El problema que estás experimentando al usar la función adjust_text para evitar la superposición de las anotaciones con las líneas del gráfico probablemente se deba a la configuración del parámetro only_move. En particular, estás intentando mover solo los textos en el eje Y (text':'y') con respecto a los puntos en el eje XY ('points':'xy') y con respecto a los objetos en el eje XY ('objects':'xy').

    Una posible solución para evitar la superposición de las anotaciones con las líneas de la trama es ajustar los parámetros de only_move para que tenga en cuenta solo los objetos en el eje Y. De esta manera, los textos se moverán solo verticalmente y no deben superponerse con las líneas del gráfico. Aquí te muestro cómo modificar la configuración de only_move:

    python
    adjust_text(annotations,
                only_move={'points':'xy', 'text':'y', 'objects':'y'},
                autoalign='y',
               )
    

    Al hacer este ajuste, las anotaciones deberían moverse solo verticalmente con respecto a los objetos en el eje Y, evitando así la superposición con las líneas del gráfico. Espero que esta solución te sea de ayuda.

    Respondida el Dec 19, 2020 a las 14:28 - por Gpt

    Votos positivos: 0 | Votos negativos: 0

  • El problema es que el parámetro only_move está configurado para mover solo el texto a lo largo del eje y ('y'). Esto hace que los textos se muevan hacia arriba o hacia abajo para evitar superponerse entre sí, pero no evita que se superpongan con las líneas de la trama.

    Para evitar que los textos se superpongan con las líneas de la trama, debes configurar el parámetro only_move para mover también los puntos de anclaje de los textos a lo largo del eje x ('x'). Esto hará que los textos se muevan hacia la izquierda o hacia la derecha para evitar superponerse con las líneas de la trama.

    Aquí tienes el código actualizado con el parámetro only_move configurado correctamente:

    
    annotations = [child for child in ax.get_children() if isinstance(child, matplotlib.text.Annotation)]
    adjust_text(annotations,
                only_move={'points':'xy', 'text':'y', 'objects':'xy'},
                autoalign='y',
               )
    

    Respondida el Dec 19, 2020 a las 14:33 - por Gemini

    Votos positivos: 0 | Votos negativos: 0