运行ggplot出现问题:no display name and no $DISPLAY environment variable

最近在用django做一个项目,关于数据可视化的。作图方面,之前用过百度的echart,这个是在前端直接调用的,这次想尝试在后台直接生成图,然后存在服务器上,之后前端再把图片显示出来就好了。

用的ggplot。

在windows下,用runserver测试,没问题。但是在服务器上,就跑不了了,出现了这样的提示:

tkinter.TclError: no display name and no $DISPLAY environment variable

查看了一下debug信息,发现貌似和Matplotlib有关,继续顺藤摸瓜。

找到了问题所在:http://matplotlib.org/faq/howto_faq.html#howto-webapp

官网的英文解释:

Many users report initial problems trying to use maptlotlib in web application servers, because by default matplotlib ships configured to work with a graphical user interface which may require an X11 connection. Since many barebones application servers do not have X11 enabled, you may get errors if you don’t configure matplotlib for use in these environments. Most importantly, you need to decide what kinds of images you want to generate (PNG, PDF, SVG) and configure the appropriate default backend. For 99% of users, this will be the Agg backend, which uses the C++ antigrain rendering engine to make nice PNGs

不想读完也没关系,大概说下怎么回事。

不同的系统有不同的用户图形接口,默认的接口在windows下跑是没有问题的,问题是我们很多的webapp都不在windows上跑,一般在linux上面,所以要更改它的默认配置,把模式更改成Agg。

纯代码解决方案

这也是大部分人在网上诸如stackoverflow的问答平台得到的解决方案,在引入pyplot、pylab之前,要先更改matplotlib的后端模式为”Agg”。直接贴代码吧!

# do this before importing pylab or pyplot
Import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot asplt

更改配置文件方案

就我的情况而言,上面那种解决方案似乎不适用,因为我是在django中使用的ggplot,它调用matplotlib的时机,我并不是很清楚。所以试了几次,都没有能把matplotlib.use('Agg')这句代码放在正确的位置上,因而也解决不了错误。

所以我转向了另一种解决方案,也是从官网启发而来。

好了,这里告诉我们,什么是backend:

http://matplotlib.org/faq/usage_faq.html#what-is-a-backend

然后这里告诉我们,怎么改配置文件:

http://matplotlib.org/users/customizing.html#customizing-matplotlib

看到下面这个地方:

matplotlibrc文件

没错,它的配置文件就是matplotlibrc,在哪里呢?不同系统不一样,我的系统是ubuntu,运行了命令whereis matlotlibrc,找到了。

matplotlibrc文件位置

编辑一下:

sudo vim /etc/matplotlibrc

找到backend这里,然后将其改成Agg,如下!

# The default backend; one of GTK GTKAgg GTKCairo GTK3Agg GTK3Cairo
# CocoaAgg MacOSX Qt4Agg Qt5Agg TkAgg WX WXAgg Agg Cairo GDK PS PDF SVG
# Template.
# You can also deploy your own backend outside of matplotlib by
# referring to the module name (which must be in the PYTHONPATH) as
# ‘module://my_backend’.
backend : Agg

保存,运行,错误消失。