He estado jugando con Numpy y matplotlib en los últimos días. Tengo problemas para intentar que matplotlib plot sea una función sin bloquear la ejecución. Sé que ya hay muchos hilos aquí en SO que hacen preguntas similares, y he buscado mucho en Google pero no he logrado que esto funcione.
He intentado usar show (block = False) como sugieren algunas personas, pero todo lo que obtengo es una ventana congelada. Si simplemente llamo a show (), el resultado se traza correctamente pero la ejecución se bloquea hasta que se cierra la ventana. De otros hilos que he leído, sospecho que si show (block = False) funciona o no depende del backend. ¿Es esto correcto? Mi back end es Qt4Agg. ¿Podrías echar un vistazo a mi código y decirme si ves algo mal? Aquí está mi código. Gracias por cualquier ayuda.
from math import *
from matplotlib import pyplot as plt
print plt.get_backend()
def main():
x = range(-50, 51, 1)
for pow in range(1,5): # plot x^1, x^2, ..., x^4
y = [Xi**pow for Xi in x]
print y
plt.plot(x, y)
plt.draw()
#plt.show() #this plots correctly, but blocks execution.
plt.show(block=False) #this creates an empty frozen window.
_ = raw_input("Press [enter] to continue.")
if __name__ == '__main__':
main()
PD. Olvidé decir que me gustaría actualizar la ventana existente cada vez que trazo algo, en lugar de crear una nueva.
fuente
plt.ion()
antesplt.show()
? Entonces no debe ser bloqueante ya que cada trama se genera en un hilo secundario.matplotlib
.Respuestas:
Pasé mucho tiempo buscando soluciones y encontré esta respuesta .
Parece que, con el fin de conseguir lo que (y yo) quiere, lo que necesita la combinación de
plt.ion()
,plt.show()
(no conblock=False
) y, lo más importante,plt.pause(.001)
(o lo que sea el tiempo que desee). La pausa es necesaria porque los eventos de la GUI ocurren mientras el código principal está inactivo, incluido el dibujo. Es posible que esto se implemente recogiendo el tiempo de un hilo inactivo, por lo que tal vez los IDE se metan con eso, no lo sé.Aquí hay una implementación que funciona para mí en python 3.5:
fuente
plt.draw
seguíplt.show(block = False)
pero luego dejó de funcionar: la figura no respondió, cerrando se bloqueó iPython. Mi solución fue eliminar cada instanciaplt.draw()
y reemplazarla porplt.pause(0.001)
. En lugar de que lo siguieranplt.show(block = False)
comoplt.draw
antes, fue precedido porplt.ion()
yplt.show()
. Ahora tengo unMatplotlibDeprecationWarning
pero me permitió trazar mis cifras, así que estoy contento con esta solución.raw_input
notinput
. Ver aquíUn truco simple que funciona para mí es el siguiente:
Ejemplo :
Nota :
plt.show()
es la última línea de mi script.fuente
Puede evitar el bloqueo de la ejecución escribiendo el diagrama en una matriz y luego mostrando la matriz en un hilo diferente. Aquí hay un ejemplo de generación y visualización de gráficos simultáneamente usando pf.screen de pyformulas 0.2.8 :
Resultado:
Descargo de responsabilidad: soy el mantenedor de pyformulas.
Referencia: Matplotlib: guardar la trama en una matriz numpy
fuente
Muchas de estas respuestas están súper infladas y, por lo que puedo encontrar, la respuesta no es tan difícil de entender.
Puedes usarlo
plt.ion()
si quieres, pero encontré que usarloplt.draw()
es igual de efectivoPara mi proyecto específico que estoy trazando imágenes, pero se puede usar
plot()
oscatter()
o lo que sea en lugar defigimage()
, no importa.O
Si estás usando una figura real.
Utilicé @ krs013, y las respuestas de @Default Picture para resolver esto
Espero que esto salve a alguien de haber lanzado cada figura en un hilo separado, o de tener que leer estas novelas solo para resolver esto
fuente
Trazado en vivo
Si la cantidad de datos es demasiado, puede reducir la velocidad de actualización con un contador simple
Mantener el diagrama después de la salida del programa
Este era mi problema real para el que no podía encontrar una respuesta satisfactoria, quería trazar que no se cerró después de que se terminó el guión (como MATLAB),
Si lo piensa, una vez finalizado el script, el programa finaliza y no hay una forma lógica de mantener la trama de esta manera, por lo que hay dos opciones
esto no fue satisfactorio para mí, así que encontré otra solución fuera de la caja
Guardar en archivo y ver en visor externo
Para esto, el guardado y la visualización deben ser rápidos y el espectador no debe bloquear el archivo y debe actualizar el contenido automáticamente
Selección de formato para guardar
los formatos basados en vectores son pequeños y rápidos
Visor rápido y ligero con actualización en vivo
Para PDF hay varias buenas opciones
En Windows uso SumatraPDF, que es gratis, rápido y ligero (solo usa 1.8 MB de RAM para mi caso)
En Linux hay varias opciones como Evince (GNOME) y Ocular (KDE)
Código de muestra y resultados
Código de muestra para enviar el trazado a un archivo
después de la primera ejecución, abra el archivo de salida en uno de los visores mencionados anteriormente y disfrute.
Aquí hay una captura de pantalla de VSCode junto con SumatraPDF, también el proceso es lo suficientemente rápido como para obtener una tasa de actualización semi-en vivo (puedo obtener cerca de 10Hz en mi configuración, solo uso
time.sleep()
entre intervalos)fuente
La respuesta de Iggy fue la más fácil de seguir para mí, pero recibí el siguiente error al hacer un
subplot
comando posterior que no estaba allí cuando solo estaba haciendoshow
:Para evitar este error, ayuda a cerrar (o borrar ) el gráfico después de que el usuario presiona enter.
Aquí está el código que funcionó para mí:
fuente
El paquete Python dibujado ahora permite actualizar una trama en tiempo real de forma no bloqueante.
También funciona con una cámara web y OpenCV, por ejemplo, para trazar medidas para cada cuadro.
Ver la publicación original .
fuente