Xshell, X11, Xming, CentOS, Tk, Tkinter, Matplotlib相关的坑

前言:最近玩机器学习项目,想把阿里云服务器(CentOS7)上python数据分析程序运行的结果可视化(绘制图表)。CentOS没有GUI,而且服务器在云上、平常通过本地Xshell终端与其进行远程交互,怎么弄?方法一,将需要可视化的数据保存到文件,然后将文件从服务器传回本地,利用自己熟悉的本地工具如Matlab、Python等对文件中数据进行可视化。方法二,不通过文件中转,直接在服务器上Python程序中运行数据可视化代码,然后通过一定的机制将运行结果(图形、图表)实时传输至本地电脑上进行显示。从本人最终实践结果来看,两种方法各有优劣,前者实现难度较低但相对繁琐,后者可视化过程实时便捷但实现过程较复杂且可视化交互响应时间受网络传输影响很大。本文主要是记录我在实现方法二过程中遇到的各种坑及其解决办法。

 

在进入主题前,有必要简单介绍标题中名词:

Xshell,一款知名度非常高的终端模拟软件,我们一般通过它来与远程主机进行SSH连接,其黄金搭档包括Xftp(用于文件传输)。

X11,就是X Window系统,用于在Unix系统上显示图形界面,11可以看作版本号。貌似CentOS7自带X11,要实现数据可视化,必须依靠它。

Xming,官方介绍是一个在 Microsoft Windows 操作系统上运行 X Window System 的自由软件。说白了,通过它可以将远程Linux主机上的图形显示在本地windows电脑上。我这用的是Xming,但是也有很多人用的是Xmanager,功能差不多。

Tk,这是一个非常强大GUI工具包。基本上所有操作系统都带有这个工具。Python中可视化核心模块tkinter依赖于它。

Tkinter,是Python中封装了Tk接口的GUI工具包。

Matplotlib,Python中绘制2维图形需要用到的库。在Python可视化过程中,一般将Matplotlib与tkinter结合,前者用于实现程序逻辑,后者用于界面绘制。

 

坑一:

1.问题描述:

在安装python3.5时,运行:./configure正常,但接下来运行:make,之后提示错误:

/usr/include/tk.h:21:3: error: #error Tk 8.5 must be compiled with tcl.h from Tcl 8.5
error Tk 8.5 must be compiled with tcl.h from Tcl 8.5

2.问题分析及解决:

这个错误 “是在说什么?TK 8.5 必须与 Tcl 8.5 中 tcl.h 一起编译。

打开 /usr/include/tk.h 文件,找到第22行:

再打开 /usr/include/tcl.h 文件,找到 TCL_MAJOR_VERSION 定义处:

问题来了,为什么这里明明 TCL_MAJOR_VERSION=8,TCL_MAJOR_VERSION=5,而在tk.h里就不成立了呢?

是不是找错文件了?找成别的 tcl.h 文件去了。于是我用 locate 命令查看是否还有其它同名的文件,也是在 path 中:

  1. [hevake_lcj@localhost:/usr/include]$ locate -r /tcl\.h$

  2. /home/hevake_lcj/Install/some-libs/tcl8.6.1/generic/tcl.h

  3. /home/hevake_lcj/Install/some-libs/tcl8.6.1/unix/tclsh

  4. /usr/bin/tclsh

  5. /usr/local/include/tcl.h

发现还有一个 /usr/local/include/tcl.h 文件,打开看看:

想必就是这个文件导致的。这个头文件在 /usr/local/ 目录,想必是之前自己下载的安装包安的吧。

解决办法:(1)把自己源码安装的卸了。(2)更新环境变量,使 /usr/include/ 优先于 /usr/local/include。

我选择了第一种。好了,我们再make。”(“”内容引自:https://my.oschina.net/hevakelcj/blog/409005

但是,我这里采用一个偷懒的办法来解决这个问题:就是直接把肇事文件 “/usr/local/include/tcl.h”隐匿掉,让安装程序看不见它!我是这样操作的:重命名为/usr/local/include/tcl.h.bak。好了,重新来一遍:./configure,make,make install。安装完成,错误消失。

 

坑二:

1.问题描述:

Python3.5中import tkinter时,提示“ImportError: No module named _tkinter”。

2.问题分析及解决:

针对这个问题,网上有很多解决方案,大多提到需要安装Tk相关的工具包:tkinter和tk-devel,但是我安装之后问题依然存在,因此怀疑是配置出了问题,找了好久总算证实了我的怀疑(参考:http://tieba.baidu.com/p/4393003896)。解决方案如下:

(1)配置文件/Python3.5.2/Modules/Setup.dist中关于tkinter的部分:

        用vi编辑打开文件Setup.dist,去掉文件中下列行的注释并修改如下:
           _tkinter _tkinter.c tkappinit.c -DWITH_APPINIT \
           -  L/usr/local/lib \
           -I/usr/local/include \
           -ltk8.5 -ltcl8.5 \ #默认是8.2
          -lX11

 (2)再次重新编译安装python:在Python安装源文件目录下依次运行  ./configure,  make,  make install这三个命令。

 

坑三:

1.问题描述:

在远程主机中Python的图形显示模块搞定后,就着手通过Xshell+Xming将远程CentOS主机中程序运行的图形结果显示在本地windows电脑上。Xshell+Xming的安装配置很简单,百度一下即可。配置完成并测试时,然而并没图形显示在本地电脑上。什么情况?开始排查时,首先发现通过SSH远程登录CentOS7后,终端提示警告:“WARNING! The remote SSH server rejected X11 forwarding request.”

2.问题分析及解决:

百度一下,大都提到是X11相关模块安装和文件/etc/ssh2/sshd2_config中X11 forwarding配置的问题,在尝试大多数攻略中提到安装和配置文件中属性修改,并重新启动sshd服务后,可惜问题依旧。又找找找,终于发现一个对路的了(参考:https://www.jianshu.com/p/24663f3491fa)。具体解决方法如下:

(1)安装模块xorg-x11-xauth:

         CentOS中运行:yum -y install xorg-x11-xauth xclock(注:同时安装xclock是为了方便测试GUI,后面会提到)

(2)配置OpenSSH服务,启用X11 Forwarding:

        CentOS中运行:vi /etc/ssh/sshd_config,并编辑文件中属性如下:

        AllowTcpFowarding  yes

        X11Fowarding  yes

(3)重启sshd服务:

       CentOS中运行: /etc/init.d/sshd restart(或者:systemctl restart service.sshd)

好了,测试一下吧,将Xming运行起来,然后在Xshell命令行输入xclock并回车,正常情况下稍等片刻应该就会在本地主机左上角出现一个如下时钟:

值得一提的是,当时在Xshell上出现提示警告:“WARNING! The remote SSH server rejected X11 forwarding request.”后,我尝试更换终端模拟软件定位问题,换用集成了X server的MobaXterm并通过SSH登录后,提示变成了:X11 forwarding request failed on channel 0。基本上是一个意思。在完成上述三步后,再次在MobaXterm中运行xclock,时钟能够正常显示。另外关于X11的原理,这篇文章说的比较清楚:https://www.cnblogs.com/lixiaochun/p/8547815.html,可以参考。

 

坑四:

1.问题描述:

这个坑与Matplotlib有关。在远程主机上运行画二维图的Python程序时,提示:

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

2.问题分析及解决:

搜索发现,这个问题的原因是在使用Matplotlib库中的pyplot模块前没有明确所使用的后端(backend)渲染器(renderer)。大部分人推荐的解决方案都是在程序中直接明确设置backend为Agg或者在Matplotlib的配置文件matplotlibrc中一劳永逸地设置backend为Agg,具体如下:

(1)在Python代码中,如:

Import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt

 

(2)在文件matplotlibrc中,添加或者变更backend属性如下:

backend : Agg

 

需要说明的是,Python使用的matplotlibrc文件在哪儿,可以通过find命令找到:

find / -name matplotlibrc

如果找不到,可以在'/root/.config/matplotlib/'路径下创建一个matplotlibrc文件。事实上,通常安装了Matplotlib后,都会有个matplotlibrc文件,可以通过find命令找到这个文件,然后对其进行修改。

然而,令人懵逼的是,以上两种方法在我这儿居然解决不了问题。又找了好久,发现一篇文章中用的不是'Agg'而是'Qt5Agg',这让我灵光乍现,我这儿用'TkAgg'试试呢。。Amazing,问题解决了。。

看完官方matplotlibrc文件中关于backend的说明,似乎就明白为什么了:

##### CONFIGURATION BEGINS HERE

## The default backend; one of GTK GTKAgg GTKCairo GTK3Agg GTK3Cairo
## 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'.
##
## If you omit this parameter, it will always default to "Agg", which is a
## non-interactive backend.

官方文档中对backend的说明在这里:https://matplotlib.org/faq/usage_faq.html#what-is-a-backend,有时间可以了解一下。

好了,全部坑踩完!

走一个简单的程序:

import matplotlib as mpl
# 如果在matplotlibrc文件中添加了backend : TkAgg, 则不需要下行
# mpl.use("TkAgg") 
import matplotlib.pyplot as plt

plt.plot([1, 2, 3])
plt.show()

稍等片刻,结果如下:

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值