【问题标题】:Matplotlib -Close window without explicit mouseclickMatplotlib - 没有显式鼠标点击关闭窗口
【发布时间】:2019-05-08 08:18:41
【问题描述】:

以下代码显示以下窗口

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") 方法如相关问题中所述,但窗口仍然存在,没有关闭,我必须关闭手动关闭它。

我需要一个简单的代码来自动化打开窗口、可视化数据、在一定时间间隔后关闭窗口的过程;然后以 for 循环的方式重复该过程。

【问题讨论】:

  • 我的意思是 something 需要发生才能关闭窗口。那会是什么?
  • 显然是一个事件,在这种情况下就像鼠标点击一样。你会怎么做?
  • 问题是show() 是一个设计的阻塞函数。这里有一个问题/答案 (stackoverflow.com/questions/11140787/closing-pyplot-windows) 可能会有所帮助,但这不是一个小问题。
  • 你想让我看看你的代码是什么样子,然后给出一个与显而易见的plt.close()不同的答案?
  • 另一个潜在问题是您正在混合使用 pylab(不再支持)和 pyplot。见matplotlib.org/faq/…

标签: python matplotlib


【解决方案1】:

这是另一种解决方案,使用显式 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()

【讨论】:

  • 回溯(最近一次调用最后一次):文件“18.py”,第 33 行,在 plt.close(fig=fig) 类型错误:close() 得到了一个意外的关键字参数 'fig '
  • 你的方法有效,你是赏金的赢家。无论如何 plt.close(fig=fig) 不起作用,我已将您的答案编辑为 plt.close() 确实有效,因此请接受编辑,以便我将您的答案标记为已接受。
  • 很好奇,编写的代码在我的机器上运行良好。也许是不同版本的 matplotlib?无论如何,很高兴你发现我的回答很有用。
【解决方案2】:

这是使用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 输出:

但是,我已经做了很多这样的可视化数据分析,而且很多时候你会想在浏览结果时来回走动,花时间看一些情节,而另一些情节不那么有趣,您只需快速跳过它们。

我知道这不是您要求的,但也许将图保存到 .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()

【讨论】:

    【解决方案3】:

    您可以将 matplotlib 绘图嵌入到使用 Python 的 GUI 库创建的窗口中,并使用 GUI 库 API 来处理该窗口。

    matplotlibuser_interfaces Examples 提供了许多使用各种 GUI 库的示例。

    我会选择使用PySide2(参见embedding_in_qt5)的Qt5,使用PySide(参见embedding_in_qt4embedding_in_qt4_wtoolbar)或Tkinter(参见embedding_in_tkembedding_in_tk_canvas)的Qt4。

    【讨论】:

      【解决方案4】:

      我已经测试了以下解决方案,并且效果很好。我只使用了 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])
      

      【讨论】:

        【解决方案5】:

        我会以不同的方式解决问题,只创建一个图形,并在每次迭代时更新内容。

        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)
        

        【讨论】:

        • 我尝试了这种方法,但没有任何反应。窗口仍然存在,并且图形没有改变,导致我需要手动关闭它。
        • @Lossofhumanidentity 我已经用完整的代码编辑了我的答案,符合我的建议
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-04-09
        • 2011-11-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多