当前位置: 首页 > 知识库问答 >
问题:

在Windows、Linux、Spyder和命令行中生成matplotlib交互式图形的可移植方法

池兴邦
2023-03-14

我正在寻找一种在Windows和Linux、命令行或Spyder中生成交互式图形的方法。例如,以下脚本:

import matplotlib.pyplot as plt
fig, ax = plt.subplots(1, 1, tight_layout=True)
#plt.ion() # doesn't seem to do much
ax.plot([0,1,2],[0,3,2])
fig.show()
#plt.show(block=False) # similar behavior as fig.show()
#plt.pause(1)
input('Press enter to quit.')

针对不同环境的行为:

>

  • Linux命令行:当脚本等待用户输入时,绘图窗口显示并响应。即使程序继续运行,窗口也会保持不变(在这个简短的例子中没有),尽管缩放按钮不再工作了。这是期望的行为。

    Windows命令行:显示一个空的无响应绘图窗口,该窗口在程序结束时消失。添加plt。pause()生成交互式绘图,但它仅在指定的秒数内响应。

    Linux/Windows Spyder和iPython,配置为自动绘图:图形显示并响应,但只有在脚本完成后。

    Linux/Windows Spyder,配置为内联打印:脚本完成后打印显示,但由于tight\u layout=Trueparameter:UserWarning:此图包括与tight\u layout不兼容的轴,因此结果可能不正确。matplotlib当前正在使用非GUI后端。(请注意,我需要紧凑的布局,因为否则通常会剪裁轴标签,或者具有多个子图的图形的边距不好。)

    Linux/Windows Spyder,内联绘图:带有plt。图(…);plt。show()(而不是图(…);图show()面向对象方式),内联图在程序执行期间显示。

    如何编写在程序执行期间(可能是在等待按键时)生成交互式绘图的代码,以便从Windows命令行、Linux命令行和Spyder正确运行?

    编辑:plt。show()而不是图show()将正确显示绘图,但在IPython之外,它会阻止脚本的执行,直到我单击figure窗口的close按钮。当有多个数字或计算尚未完成时,这相当麻烦。和plt。show(block=False)具有与图show()相同的行为。

    我使用非定制的Anaconda 5.1环境与Python 3.6.4,matplotlib 2.1.2,spyder 3.2.6。在Spyder:工具

  • 共有2个答案

    龚俊捷
    2023-03-14

    这里有一种方法可以工作,但并不适用于所有环境:

    import matplotlib.pyplot as plt
    import sys
    import matplotlib
    
    def plt_show_interactive():
        """Show plot windows, with interaction if possible; prompt to continue.""" 
        in_ipython = ('get_ipython' in globals())
        inline_backend = ('inline' in matplotlib.get_backend())
        in_linux = (sys.platform == 'linux')
    
        if inline_backend:
            plt.show()
        elif not in_linux and in_ipython:
            print("Press Ctrl-C to continue.")
            try:    
                while True:
                    plt.pause(0.5)
            except KeyboardInterrupt:
                print("Continuing.")
        elif in_linux and not in_ipython:
            # Command line: plots are interactive during wait for input.
            plt.show(block=False)
            input("Press ENTER to continue.")
        elif in_linux and in_ipython:
            # Loop with plt.pause(1) causes repeated focus stealing.
            plt.pause(1)
            print("Sorry, plots are not interactive until program has finished.")
        elif not in_linux and not in_ipython:
            # Ctrl-C is handled differently here.
            plt.pause(1)
            input("Sorry, not interactive. Press ENTER to continue.")
    
    
    def prompt_if_not_ipython(verb="end"):
        """Ask user to press ENTER if not we're not inside IPython."""
        if ('get_ipython' not in globals()):
            input("Press ENTER to %s." % verb)
    
    
    fig, ax = plt.subplots(1, 1, tight_layout=True)
    ax.plot([0,1,2],[0,3,2])
    
    plt_show_interactive()
    prompt_if_not_ipython()
    
    慕容坚
    2023-03-14

    似乎以下是你想要的:

    import matplotlib.pyplot as plt
    
    fig, ax = plt.subplots(1, 1, tight_layout=True)
    
    plt.ion()
    ax.plot([0,1,2],[0,3,2])
    
    plt.show()
    plt.pause(0.1)
    
    input('Press enter to quit.')
    plt.close()
    

    通常,python程序的计算是线性的。这与希望有一个阻塞命令行(input)而不是一个非阻塞GUI的愿望相矛盾
    上面的情况是创建了GUI,但没有启动任何propper事件循环。因此,即使在显示GUI之后,代码也可以继续执行。这样做的缺点显然是,如果没有事件循环,就无法与GUI交互。

    如果需要显示绘图窗口,并且需要一些用户输入,或者在显示完全交互图形后要执行进一步的代码,则可以在GUI事件循环中运行此类代码。

    import matplotlib.pyplot as plt
    
    def run_after(callback, pause=10, figure=None):
        figure = figure or plt.gcf()
        timer = figure.canvas.new_timer(interval=pause)
        timer.single_shot = True
        timer.add_callback(callback)
        timer.start()
        return timer
    
    
    fig, ax = plt.subplots(1, 1, tight_layout=True)
    ax.plot([0,1,2],[0,3,2])
    
    # This function contains the code to be executed within the GUI event loop
    def mycallback():
        import tkinter
        from tkinter import simpledialog
        root = tkinter.Tk()
        root.withdraw()
        w = simpledialog.askinteger("Title", "How many numbers do you want to print")
    
        for i in range(w):
            print(i)
    
    
    cb = run_after(mycallback)
    
    plt.show()
    
     类似资料:
    • 问题内容: 我在家中使用linux,但在学校中我们使用Windows7。我想在我的USB上安装python,以便可以在Windows和linux上使用它(ubuntu 13.04)。有没有办法可以在USB上安装python,以便win和linux计算机都可以使用它?我对python 2.7更加感兴趣。我在Linux机器上安装了Wine。可能不理想,但我可以使用便携式python并在wine下运行它

    • 我从Python(x,y)2.7升级。2.3至2.7。Windows 7中的6.0(我很高兴看到我终于可以键入,并再次在对象检查器中查看文档字符串),但现在绘图不再像以前那样工作。 以前(Spyder 2.1.9,IPython 0.10.2,matplotlib 1.2.1),当我绘制这个脚本时,例如,它会在交互式窗口中并排绘制子情节: 现在(Spyder 2.2.5、IPython 1.2.0

    • 问题内容: 我正在尝试通过paramiko运行交互式命令。该cmd执行尝试提示输入密码,但是我不知道如何通过paramiko的exec_command提供密码,并且执行挂起。如果cmd执行期望交互输入,是否可以将值发送到终端? 有谁知道如何解决?谢谢。 问题答案: 完整的paramiko发行版附带了很多很好的演示。 在demos子目录中,并有完整的交互式TTY示例,这可能对您的情况有些过分。 在您

    • 我创建了一个使用GUI的小型Java应用程序,我的几个有Windows的朋友让我把它发送给他们。我希望尽可能避免安装等步骤。。。,所以我想知道哪种方式最好。 所以我从NetBeans构建了. jar,当我运行它时,它运行得非常好。从那时起,我试图为Windows生成一个可移植的. exe文件,我可以发送它们,它们可以在没有任何先前步骤的情况下打开(前提是它们有一个JRE)。所以我下载了JSmth、

    • 问题内容: 我正在尝试使用带有适当命令的命令自动创建开发Docker映像。我需要在命令中运行的脚本之一希望用户单击以阅读其许可协议。因此,有两个问题: ?中所有命令的输出在哪里? 可以与上述命令进行交互的解决方案是什么?现在,命令陷入僵局,要求用户无限循环输入。 问题答案: 在构建过程中,命令的输出显示在您的终端中。Docker构建过程是完全非交互的,因此您必须找到某种方式来自动接受这些条款(几乎

    • 我试图使用命令和适当的自动创建开发Docker映像。我需要在命令中运行的一个脚本希望用户单击并阅读他们的许可协议。因此有两个问题: 中所有 命令的输出在哪里? 有什么解决方案可以与上述命令交互?现在,命令只能在无限循环中向用户请求输入。