Matplotlib -Закрыть окно без явного щелчка мышью - PullRequest
0 голосов
/ 06 декабря 2018

следующий код отображает следующее окно :

import numpy as np 
import matplotlib.pylab as pl
import matplotlib.gridspec as gridspec
from matplotlib import pyplot as plt 

def plot_stuff(x,y,z):  
    gs = gridspec.GridSpec(3, 1) 
    plt.style.use('dark_background')
    pl.figure("1D Analysis")
    ax = pl.subplot(gs[0, 0]) 
    ax.set_ylabel('X VALUE')
    pl.plot(x, color="red")
    ax = pl.subplot(gs[1, 0]) 
    ax.set_ylabel('Y VALUE')
    pl.plot(y, color="green")    
    ax = pl.subplot(gs[2, :])
    ax.set_ylabel('Z VALUE')
    pl.plot(z, color="blue")
    plt.show()

Как мнезакрыть окно без явного щелчка мышью?

Мне нужно визуализировать МНОГО данных, поэтому я ищу способ автоматизации процесса открытия и закрытия окон.

Я знаю, что plt.show() - это операция блокировки, и я 'мы пытались использовать plt.close("all") метод , как упоминалось в связанных вопросах , но окно остается там, не закрывается, и мне приходится закрывать его вручную.

Мне нужен простой код для автоматизации процесса открытия окна, визуализации данных, закрытия окна через определенный промежуток времени;и затем повторите процедуру в режиме цикла.

Ответы [ 5 ]

0 голосов
/ 02 февраля 2019

Вот другой подход, использующий animation:

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation

interval = 100  # in ms
rescale_axis = False

# Properties of the data
num_batches = 10
num_obs = [20, 30, 10]
feature_names = ['X VALUE', 'Y VALUE', 'Z VALUE']
feature_colors = ['red', 'green', 'blue']
num_features = len(feature_names)
data_to_plot = [np.random.rand(num_batches, num_obs[f]) for f in range(num_features)]

# Create the figure
plt.style.use('dark_background')
fig, axes = plt.subplots(num_features, 1)
fig.canvas.set_window_title('1D Analysis')
# Initial plot
lines = []
for f in range(num_features):
    line, = axes[f].plot(data_to_plot[f][0, :], c=feature_colors[f])
    lines.append(line)
    axes[f].set_ylabel(feature_names[f])
    if not rescale_axis:
        axes[f].set_ylim(0, 1)

def plot_stuff(xyz):
    x, y, z = xyz
    for f, data in enumerate([x, y, z]):
        lines[f].set_data([ix for ix in range(len(data))], data)
        if rescale_axis:
            axes[f].relim()
            axes[f].autoscale_view()
    return lines

def data_gen():
    for x, y, z in zip(*data_to_plot):
        yield x, y, z

ani = animation.FuncAnimation(fig, plot_stuff, data_gen, interval=interval)
ani.save('results.gif', dpi=80, writer='imagemagick')
plt.show()

, из которого можно даже извлечь вывод .gif: git output example

Однако яЯ провел такой визуальный анализ данных, и много раз вам приходилось переходить назад и вперед при просмотре результатов, занимая время для одних графиков, в то время как другие не такие интересные, и вы просто их быстро пропускаете.

Я знаю, что это не то, что вы просили, но, возможно, было бы полезно сохранить графики в .pdf вместо этого, с каждым графиком на отдельной странице:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.backends.backend_pdf import PdfPages

rescale_axis = False
output_pdf_file = 'results.pdf'

# Properties of the data
num_batches = 10
num_obs = [20, 30, 10]
feature_names = ['X VALUE', 'Y VALUE', 'Z VALUE']
feature_colors = ['red', 'green', 'blue']
num_features = len(feature_names)
data_to_plot = [np.random.rand(num_batches, num_obs[f]) for f in range(num_features)]

# Create the figure
plt.style.use('dark_background')
fig, axes = plt.subplots(num_features, 1)
fig.canvas.set_window_title('1D Analysis')

# Initial plot
lines = []
for f in range(num_features):
    line, = axes[f].plot(data_to_plot[f][0, :], c=feature_colors[f])
    lines.append(line)
    axes[f].set_ylabel(feature_names[f])
    if not rescale_axis:
        axes[f].set_ylim(0, 1)

def plot_stuff(x, y, z):
    for f, data in enumerate([x, y, z]):
        lines[f].set_data([ix for ix in range(len(data))], data)
        if rescale_axis:
            axes[f].relim()
            axes[f].autoscale_view()
    return lines

with PdfPages(output_pdf_file) as pdf:
    for x, y, z in zip(*data_to_plot):
        plot_stuff(x, y, z)
        pdf.savefig()
0 голосов
/ 31 января 2019

Я протестировал приведенное ниже решение, и оно работает отлично.Я использовал только модуль pylab.

import numpy as np 
import matplotlib.pylab as pl
import matplotlib.gridspec as gridspec

def plot_stuff(x,y,z):
    pl.ion() # interactive mode on
    gs = gridspec.GridSpec(3, 1) 
    pl.style.use('dark_background')
    pl.figure("1D Analysis")
    ax = pl.subplot(gs[0, 0]) 
    ax.set_ylabel('X VALUE')
    pl.plot(x, color="red")
    ax = pl.subplot(gs[1, 0]) 
    ax.set_ylabel('Y VALUE')
    pl.plot(y, color="green")    
    ax = pl.subplot(gs[2, :])
    ax.set_ylabel('Z VALUE')
    pl.plot(z, color="blue")
    pl.show()
    pl.pause(3) # pause for 3 sec
    pl.close()  # close the window

items = [np.random.rand(100, 3),
            np.random.randint(10, size=(100, 3)),
            np.random.rand(100, 3)]


for item in items:
    plot_stuff(x=item[:, 0], y=item[:, 1], z=item[:, 2])
0 голосов
/ 30 января 2019

Вы можете встроить свой график matplotlib в окно, созданное с помощью библиотеки GUI для python, и использовать API библиотеки GUI для обработки окна.

Примеры matplotlib user_interfaces предоставляют множество примеров с использованием различных библиотек GUI.

Я бы пошел на Qt5, используя PySide2 (см. embedding_in_qt5 ), Qt4, используя PySide (см. embedding_in_qt4 или embedding_in_qt4_wtoolbar ) или Tkinter (см. embedding_in_tk или embedding_in_tk_canvas ).

0 голосов
/ 31 января 2019

Вот еще одно решение, использующее явный оператор close для закрытия и воссоздания фигуры на каждой итерации

from matplotlib import gridspec
import matplotlib.pyplot as plt
import numpy as np


def plot_stuff(x, y, z):
    gs = gridspec.GridSpec(3, 1)
    plt.style.use('dark_background')
    fig = plt.figure("1D Analysis")
    ax = plt.subplot(gs[0, 0])
    ax.set_ylabel('X VALUE')
    plt.plot(x, color="red")
    ax = plt.subplot(gs[1, 0])
    ax.set_ylabel('Y VALUE')
    plt.plot(y, color="green")
    ax = plt.subplot(gs[2, :])
    ax.set_ylabel('Z VALUE')
    plt.plot(z, color="blue")
    return fig


things_to_plot = [np.random.random(size=(100, 3)),
                  np.ones((100, 3)),
                  np.random.random(size=(100, 3))]
delay = 5

if __name__ == "__main__":
    plt.ion()
    for things in things_to_plot:
        fig = plot_stuff(x=things[:, 0], y=things[:, 1], z=things[:, 2])
        plt.show()
        plt.pause(delay)
        plt.close()
0 голосов
/ 06 декабря 2018

Я бы по-другому решил проблему и создал бы только одну фигуру и обновлял бы содержимое на каждой итерации.

import matplotlib.pyplot as plt
from matplotlib import gridspec
from matplotlib.axes import Axes
import numpy as np
from matplotlib.figure import Figure


def plot_stuff(x, y, z, fig: Figure = None):
    print(f"plotting x[{x.shape}],y[{y.shape}],z[{z.shape}] in fig[{fig.__repr__()}]")
    if fig is None:
        fig = plt.gcf()
    fig.clf()
    gs = gridspec.GridSpec(3, 1)
    fig.canvas.set_window_title("1D Analysis")
    ax1: Axes = plt.subplot(gs[0, 0])
    ax1.set_ylabel('X VALUE')
    ax1.plot(x, color="red")
    ax2: Axes = plt.subplot(gs[1, 0])
    ax2.set_ylabel('Y VALUE')
    ax2.plot(y, color="green")
    ax3: Axes = plt.subplot(gs[2, :])
    ax3.set_ylabel('Z VALUE')
    ax3.plot(z, color="blue")
    fig.canvas.draw_idle()


things_to_plot = [np.random.random(size=(100, 3)),
                  np.ones((100, 3)),
                  np.random.random(size=(100, 3))]
delay = 5

if __name__ == "__main__":
    plt.ion()
    plt.show()
    fig = plt.figure()
    for things in things_to_plot:
        plot_stuff(x=things[:, 0], y=things[:, 1], z=things[:, 2], fig=fig)
        plt.draw()
        plt.pause(delay)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...