zoukankan      html  css  js  c++  java
  • ssh调用matplotlib绘图报错RuntimeError: Invalid DISPLAY variable

    1.问题:在本地用matplotlib绘图可以,但是在ssh远程绘图的时候会报错 RuntimeError: Invalid DISPLAY variable

    2.原因:matplotlib的默认backend是TkAgg,而FltkAgg, GTK, GTKAgg, GTKCairo, TkAgg , Wx or WxAgg这几个backend都要求有GUI图形界面的,所以在ssh操作的时候会报错.

    import matplotlib.pyplot as plt
    Backend TkAgg is interactive backend. Turning interactive mode on.
    
    plt.get_backend()
    Out[3]: u'TkAgg'

    3.解决方法:指定不需要GUI的backend(Agg, Cairo, PS, PDF or SVG

    import matplotlib.pyplot as plt
    plt.switch_backend('agg')

    4.源码

    查看plt.switch_backend()的源码实现和解析:

    复制代码
    def switch_backend(newbackend):
        """
        Switch the default backend.  This feature is **experimental**, and
        is only expected to work switching to an image backend.  e.g., if
        you have a bunch of PostScript scripts that you want to run from
        an interactive ipython session, you may want to switch to the PS
        backend before running them to avoid having a bunch of GUI windows
        popup.  If you try to interactively switch from one GUI backend to
        another, you will explode.
    
        Calling this command will close all open windows.
        """
        close('all')
        global _backend_mod, new_figure_manager, draw_if_interactive, _show
        matplotlib.use(newbackend, warn=False, force=True)
        from matplotlib.backends import pylab_setup
        _backend_mod, new_figure_manager, draw_if_interactive, _show = pylab_setup()
    复制代码

    查看matplotlib.use()的源码:

    复制代码
    def use(arg, warn=True, force=False):
        """
        Set the matplotlib backend to one of the known backends.
    
        The argument is case-insensitive. *warn* specifies whether a
        warning should be issued if a backend has already been set up.
        *force* is an **experimental** flag that tells matplotlib to
        attempt to initialize a new backend by reloading the backend
        module.
    
        .. note::
    
            This function must be called *before* importing pyplot for
            the first time; or, if you are not using pyplot, it must be called
            before importing matplotlib.backends.  If warn is True, a warning
            is issued if you try and call this after pylab or pyplot have been
            loaded.  In certain black magic use cases, e.g.
            :func:`pyplot.switch_backend`, we are doing the reloading necessary to
            make the backend switch work (in some cases, e.g., pure image
            backends) so one can set warn=False to suppress the warnings.
    
        To find out which backend is currently set, see
        :func:`matplotlib.get_backend`.
    
        """
        # Lets determine the proper backend name first
        if arg.startswith('module://'):
            name = arg
        else:
            # Lowercase only non-module backend names (modules are case-sensitive)
            arg = arg.lower()
            name = validate_backend(arg)
    
        # Check if we've already set up a backend
        if 'matplotlib.backends' in sys.modules:
            # Warn only if called with a different name
            if (rcParams['backend'] != name) and warn:
                warnings.warn(_use_error_msg)
    
            # Unless we've been told to force it, just return
            if not force:
                return
            need_reload = True
        else:
            need_reload = False
    
        # Store the backend name
        rcParams['backend'] = name
    
        # If needed we reload here because a lot of setup code is triggered on
        # module import. See backends/__init__.py for more detail.
        if need_reload:
            reload(sys.modules['matplotlib.backends'])
    复制代码

    参考:DISPLAY error matplotlib http://chewpichai.blogspot.com/2008/01/display-error-matplotlib.html 。原文可能被墙了,需要设法翻一下。

    原文内容:

    复制代码
    DISPLAY error matplotlib
    When error occur about this "$DISPLAY not set" when you run python code that use matplotlib this happened because your matplotlib backend is set to FltkAgg, GTK, GTKAgg, GTKCairo, TkAgg , Wx or WxAgg they required a GUI that why error occur.
    
    To solve this you must specific other backend that not required GUI (Agg, Cairo, PS, PDF or SVG) when use matplotlib like this 
    
    In code import matplotlib matplotlib.use('Agg')
    In command line use -d option python subplot_demo.py -dAgg Remember when call savefig('filename') don't give it extension this will handle by backend that you specific e.g Agg will create file filename.png
    复制代码
     
  • 相关阅读:
    三种适配器模式 总结和使用场景
    (面试)Statement和PrepareStatement有什么区别
    知识点:Oracle+表连接方式(内连接-外连接-自连接)+详解 来自百度文库
    (面试题)有关Integer
    sessionId与cookie 的关系(百度文库)
    (面试)将1到100的随机数插入到长度为100的数组中,保证不会有重复元素
    如何通过sql的insert语句插入大量字符串到oracle的clob字段?
    (面试题)synchronized 和 java.util.concurrent.locks.Lock 的异同
    【转】java io 流 设计模式
    (面试题)两个对象值相同 (x.equals(y) == true) ,但却可有不同的 hash code ,这 句话对不对
  • 原文地址:https://www.cnblogs.com/hizhaolei/p/10456961.html
Copyright © 2011-2022 走看看