plt.gcf() no muestra instancia previa de un complot

Quiero guardar una instancia de una trama en un objeto para que pueda mostrarla más tarde llamando a ese objeto.

import numpy as np
import matplotlib.pyplot as plt

x = np.arange(0, 10, 0.1)
y1 = x
y2 = np.sin(x)

plt.plot(x, y1, linewidth=1, color = 'deepskyblue')
fig1 = plt.gcf()

plt.plot(x, y2, linewidth=1, color = 'red')
fig2 = plt.gcf()

En este ejemplo, primero trazo una línea azul (y1=x) y uso plt.gcf() para salvar una instancia de esta parcela en fig1. Luego agrego una curva roja (y2=sin(x)) a la trama y uso plt.gcf() de nuevo para salvar esta parcela fig2. Ahora, espero que cuando llamo fig1 Sólo tengo la línea azul, y cuando llamo fig2 Tengo ambas líneas. Así (estoy en Jupyter):

fig1   # or fig1.show() if not in Jupyter

Sólo curva azul
Only blue curve

fig2 

Ambas curvas
Both curves

Pero, en realidad, cuando llamo fig1 y fig2, ambos muestran ambas curvas (como la segunda imagen). ¿Puede alguien por favor ayudar cómo puedo obtener correctamente una instancia de cada parcela para que pueda mostrar cada uno de ellos más adelante cuando quiera?

Pregunta hecha hace 3 años, 4 meses, 27 días - Por csharpsorcerer


3 Respuestas:

  • Necesitas fuerza matplotlib para dibujar la figura estableciendo un plot.show() en su código:

    import numpy as np
    import matplotlib.pyplot as plt
    
    x = np.arange(0, 10, 0.1)
    y1 = x
    y2 = np.sin(x)
    
    plt.plot(x, y1, linewidth=1, color = 'deepskyblue')
    plt.show()
    fig1 = plt.gcf()
    
    plt.plot(x, y2, linewidth=1, color = 'red')
    plt.show()
    fig2 = plt.gcf()
    

    Utilizando la función plt.plot() Siempre trama el eje actual (si no hay eje presente, se crea uno nuevo). También puedes decir matplotlib explícitamente para abrir una nueva figura:

    import numpy as np
    import matplotlib.pyplot as plt
    
    x = np.arange(0, 10, 0.1)
    y1 = x
    y2 = np.sin(x)
    
    # open first figure
    fig1 = plt.figure()
    # plot
    plt.plot(x, y1, linewidth=1, color = 'deepskyblue')
    
    # open second figure
    fig2 = plt.figure()
    #plot
    plt.plot(x, y2, linewidth=1, color = 'red')
    

    Aunque esto ya arregla su problema, se considera buena práctica utilizar una versión orientada al objeto de este tipo:

    import numpy as np
    import matplotlib.pyplot as plt
    
    x = np.arange(0, 10, 0.1)
    y1 = x
    y2 = np.sin(x)
    
    # open first figure, axis
    fig1, ax1 = plt.subplots()
    # plot
    ax1.plot(x, y1, linewidth=1, color = 'deepskyblue')
    
    # open second figure, axis
    fig2, ax2 = plt.subplots()
    #plot
    ax2.plot(x, y2, linewidth=1, color = 'red')
    

    En todos los casos, obtendrá: output

    Ahora, ¿por qué no necesitas? plt.show() en los otros enfoques? Bueno, matplotlib al abrir explícitamente una nueva figura/eje, es obvio que el eje anterior está terminado y se puede dibujar.

    El último enfoque es el más claro como usted dice exactamente qué figura y qué eje usted está considerando.

    Respondida el Dec 18, 2020 a las 22:35 - por binarybard1cc8

    Votos positivos: 0 | Votos negativos: 0

  • El problema que estás experimentando se debe a la forma en que estás guardando las instancias de las figuras en los objetos fig1 y fig2. En lugar de guardar una instancia de la figura en sí misma, estás guardando la figura "actual" en ese momento, por lo que ambas figuras terminan conteniendo la última trama trazada.

    Para solucionar este problema, puedes crear explícitamente una nueva figura y un nuevo eje antes de trazar cada gráfico, y luego guardar esas figuras y ejes en una lista. De esta manera, podrás acceder a cada gráfico individualmente más adelante. Aquí te dejo un ejemplo de cómo modificar tu código:

    python
    import numpy as np
    import matplotlib.pyplot as plt
    
    x = np.arange(0, 10, 0.1)
    y1 = x
    y2 = np.sin(x)
    
    fig1, ax1 = plt.subplots()
    ax1.plot(x, y1, linewidth=1, color='deepskyblue')
    
    fig2, ax2 = plt.subplots()
    ax2.plot(x, y2, linewidth=1, color='red')
    
    

    Guardar las figuras y ejes en una lista

    figuras = [(fig1, ax1), (fig2, ax2)]

    Para mostrar la primera figura

    figuras[0][0].show()

    Para mostrar la segunda figura

    figuras[1][0].show()

    Con este enfoque, cada gráfico se trazará en una figura diferente y podrás acceder a ellos individualmente más adelante.

    Respondida el Dec 19, 2020 a las 22:35 - por Gpt

    Votos positivos: 0 | Votos negativos: 0

  • El problema radica en el uso de plt.gcf(). Esta función devuelve la figura actual, que es una propiedad global del módulo matplotlib.pyplot. Cuando llamas plt.gcf() varias veces, sobrescribes la figura actual con la nueva figura que se está creando.

    Para crear instancias separadas de cada trama, debes crear una nueva figura para cada una antes de trazarla. Puedes hacer esto usando la función plt.figure(). Aquí tienes un código modificado que creará dos figuras separadas:

    python
    import numpy as np
    import matplotlib.pyplot as plt
    
    x = np.arange(0, 10, 0.1)
    y1 = x
    y2 = np.sin(x)
    
    

    Crea una nueva figura para la primera trama

    fig1 = plt.figure() plt.plot(x, y1, linewidth=1, color='deepskyblue')

    Crea una nueva figura para la segunda trama

    fig2 = plt.figure() plt.plot(x, y2, linewidth=1, color='red')

    Muestra la primera trama

    fig1.show()

    Muestra la segunda trama

    fig2.show()

    Ahora, cuando llames fig1, solo mostrará la línea azul, y cuando llames fig2, solo mostrará la curva roja.

    Respondida el Dec 19, 2020 a las 22:47 - por Gemini

    Votos positivos: 0 | Votos negativos: 0