我试图用pyplot绘制一个简单的图形,例如:
import matplotlib.pyplot as plt
plt.plot([1,2,3],[5,7,4])
plt.show()
但是这个图没有出现,我得到了以下消息:
UserWarning: Matplotlib is currently using agg, which is a non-GUI backend, so cannot show the figure.
我在几个地方看到必须使用以下命令更改matplotlib的配置:
import matplotlib
matplotlib.use('TkAgg')
import matplotlib.pyplot as plt
我这样做了,但得到了一个错误消息,因为它找不到一个模块:
ModuleNotFoundError: No module named 'tkinter'
然后,我尝试使用pip install tkinter(在虚拟环境中)安装“tkinter”,但它没有找到它:
Collecting tkinter
Could not find a version that satisfies the requirement tkinter (from versions: )
No matching distribution found for tkinter
我还应该提到,我是在使用虚拟环境的Pycharm Community Edition IDE上运行所有这些,并且我的操作系统是Linux/Ubuntu 18.04。
我想知道我如何解决这个问题,以便能够显示图形。
解决方案1:安装GUI后端tk
我找到了解决问题的方法(感谢ImportanceOfBeingErnest的帮助)。
我所要做的就是通过Linux bash终端使用以下命令安装tkinter:
sudo apt-get install python3-tk
而不是用pip或直接在Pycharm的虚拟环境中安装。
解决方案2:安装任何matplotlib支持的GUI后端
解决方案1工作得很好,因为你得到了一个GUI后端…在这种情况下是TkAgg
但是你也可以通过安装任何matplolib GUI后端来解决这个问题,比如Qt5Agg, GTKAgg, Qt4Agg等
例如,PIP安装pyqt5也将解决这个问题
注意:
通常,当你安装matplotlib并且你试图在GUI窗口中显示一个图形,而你没有用于GUI显示的python模块时,会出现这个错误。
matplotlib的作者使pypi软件deps不依赖于任何GUI后端,因为有些人需要matplotlib而不需要任何GUI后端。
万一这能帮到谁呢。
Python版本:3.7.7
平台:Ubuntu 18.04.4 LTS
这是默认的python 3.6.9版本,但是我已经在上面安装了我自己的3.7.7版本的python(安装从源代码构建它)
即使帮助('module')在列表中显示Tkinter, Tkinter也没有工作。
下面的步骤对我很有效:
Sudo apt-get install tk-dev。
重新构建python:
1. 导航到你的python文件夹并运行检查:
cd Python-3.7.7
sudo ./configure --enable-optimizations
使用make命令构建:
Sudo make -j 8——这里8是处理器的数量,使用nproc命令检查你的。
安装使用:
Sudo做altinstall
不要使用sudo make install,它会覆盖默认的3.6.9版本,以后可能会很乱。
现在查看tkinter
Python3.7 -m tkinter
一个窗口框将弹出,你的tkinter已经准备好了。
这适用于R网状结构。在这里找到的。
1: matplotlib。使用“tkaggs”
前
2: matplotlib$use('tkagg')
例如:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import style
import matplotlib
matplotlib.use( 'tkagg' )
style.use("ggplot")
from sklearn import svm
x = [1, 5, 1.5, 8, 1, 9]
y = [2, 8, 1.8, 8, 0.6, 11]
plt.scatter(x,y)
plt.show()
在WSL上使用X服务器
确保您的X服务器工作正常。如果无法连接到X显示器,Matplotlib会提示此错误。
Windows防火墙配置
注意windows防火墙!我把WSL Debian换成了Ubuntu,不记得防火墙规则了。
我用这篇文章来配置windows防火墙规则,使X服务器正常工作。这种方法避免了过于宽松的规则,使得任何人都可以使用你的X服务器。
信上说:
如果您已经安装了X11服务器,Windows可能已经创建了防火墙规则,这些规则会打乱上面的配置。在“高级安全Windows防御防火墙”中搜索并删除它们。
You will now need to configure Windows Firewall to permit connections from WSL2 to the X11 display server. You will install the display server in the next step. We do this step first to avoid Windows Firewall from auto-creating an insecure firewall rule when you run the X11 display server. Many guides on X11 forwarding and WSL2 make this firewall rule too permissive, allowing connections from any computer to your computer. This means someone could theoretically, if they are on your same network, start sending graphical display information to your computer.
To avoid this, we will make Windows Firewall only accept internet traffic from the WSL2 instance.
To set this up, you can copy the below to a script and run it from within WSL2:
#!/bin/sh
LINUX_IP=$(ip addr | awk '/inet / && !/127.0.0.1/ {split($2,a,"/"); print a[1]}')
WINDOWS_IP=$(ip route | awk '/^default/ {print $3}')
# Elevate to administrator status then run netsh to add firewall rule
powershell.exe -Command "Start-Process netsh.exe -ArgumentList \"advfirewall firewall add rule name=X11-Forwarding dir=in action=allow program=%ProgramFiles%\VcXsrv\vcxsrv.exe localip=$WINDOWS_IP remoteip=$LINUX_IP localport=6000 protocol=tcp\" -Verb RunAs"
手动方法:
Alternatively, you can manually add the rule through a GUI by doing the following:
Open "Windows Defender Firewall with Advanced Security"
Click add new rule brings up the New Rule Wizard (next to navigate between each section):
Rule type: Custom
Program: "This program path:" %ProgramFiles%\VcXsrv\vcxsrv.exe
Protocol and ports
Protocol type: TCP
Local port: 6000
Remote port: any
Scope
Local IP address: Obtain the IP address to put in by running the below command in WSL2
ip route | awk '/^default/ {print $3}'
remote IP addresses
Obtain IP address to enter by running the below in WSL2
ip addr | awk '/inet / && !/127.0.0.1/ {split($2,a,"/"); print a[1]}'
Action: "Allow the connection
Profile: Selection Domain, Private, and Public
Name: "X11 forwarding"
这个问题的解决方法是:
确保把这条线放好
%matplotlib inline
在代码头部
像这样
# In an IPython notebook¶
# This magic just sets up matplotlib's interactive mode
%matplotlib inline
# So you have to explicitely import the module into the namespace
import matplotlib.pyplot as pl
import numpy as np
# Create the figure object
fig = pl.figure(figsize=(12, 8))
x = np.arange(0, 4 * np.pi, 0.1)
y = np.sin(x)
pl.plot(x, y)
%matplotlib inline turns on “inline plotting”, where plot graphics will appear in your notebook. This has important implications for interactivity: for inline plotting, commands in cells below the cell that outputs a plot will not affect the plot. For example, changing the color map is not possible from cells below the cell that creates a plot. However, for other backends, such as qt4, that open a separate window, cells below those that create the plot will change the plot - it is a live object in memory. If you are not using matplotlib in interactive mode at all, figures will only appear if you invoke
有关%matplotlib内联的更多信息,请参阅此链接