Python GUI:Tkinter——05


本章将续第四章 Python GUI:Tkinter——04 。在第四章的总结中,我们提出一个问题:如何将结果可视化,并展示在我们的 GUI 中呢?比如,做一个投资理财的 GUI,必须根据数据,把指数啥的都画进去吧?不然,你以为只要展示几张美眉图片就能吸引用户吗?

那么怎么办呢?Python 中提供了一个很强大的可视化模块,matplotlib,是否能将 matplotlib 模块集成到我们的 GUI 中呢?这就是今天我们要做的事情了。

Matplotlib 基本应用

为了大家能够快速地熟悉 matplotlib 语法,我们首先来看几个简单应用。

最简单的画图

import numpy as np
import matplotlib.pyplot as plt
from pylab import show

x = np.arange(0,5,0.1)
y = np.sin(x)
#显示中文
plt.rcParams['font.sans-serif']=['SimHei']
plt.rcParams['axes.unicode_minus'] = False

plt.figure()    #以下代码画出ROC曲线
plt.plot(x,y,'k',label='曲线')    #加入 legend
plt.plot([0,1],[0,1],'k--',label='直线')
plt.axis([-0.05,1,0,1.05])  #设置显示范围
plt.xlabel('我是x轴')    # xlabel
plt.ylabel('我是y轴')
plt.legend(loc='best')    #显示 legend,并设置位置

在这里插入图片描述
为什么称之为简单呢?首先,他用了 plt 来画图,再者,他只能展示一个图。为了完善这一点,我们还需要看一下下面的代码:

画图——多多益善

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
plt.figure(figsize=(12,4))    #设置图片的大小,其中 12 是宽度,4 是高度
plt.subplots_adjust(left=0.125, bottom=None, right=0.9, top=None,
                wspace=0.3, hspace=None)    #设置子图们的间距
plt.rcParams['font.sans-serif']=['SimHei']    #中文
plt.rcParams['axes.unicode_minus'] = False
plt.subplot(1,2,1)    #画子图,并把当前画图设置为子图环境,这句话很重要,很有深度的,特别是环境这个词。
#  另外 1,2,1 前两位代表 行、列,后一位代表第几张图(从左上角算起,顺时针)
xValue = list(np.arange(0,1,0.001))    
yValue = [np.random.rand() for x in xValue]
plt.title(u'无相关性',fontsize=20)    #设置图片的 title
plt.xlabel('x1',fontsize=20)
plt.ylabel('x2',fontsize=20)
plt.scatter(xValue, yValue, s=20, c="g", marker='o')

plt.subplot(1,2,2)
xValue = list(np.arange(0,1,0.001))
yValue = [x*np.random.rand() for x in xValue]
plt.title(u'存在一定相关性',fontsize=20)
plt.xlabel('x1',fontsize=20)
plt.ylabel('x2',fontsize=20)
plt.scatter(xValue, yValue, s=20, c="r", marker='o')
plt.show()

这里的画图,还是用了 plt,因此也比较简单易懂,也是笔者主要的画图风格。
在这里插入图片描述

剑荡八荒式画图

所谓剑荡八荒,就是一个代码哗啦的一下画出几张图,如何画,请看下面:

import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif']=['SimHei']    #画图时显示中文字体
plt.rcParams['axes.unicode_minus'] = False

fig, axes = plt.subplots(10,1, figsize=(8, 6),subplot_kw={'xticks':[], 'yticks':[]},
                        gridspec_kw=dict(hspace=0.1, wspace=0.1))
for i, ax in enumerate(axes.flat):
    ax.plot([0,1])
    ax.set_xlabel('日期序列',fontsize=14)
    ax.set_ylabel('我是y轴')

在这里插入图片描述
好了,画图就到这儿了。你要记住,有两种画图,一种是 plt、一种是 ax。什么,还有其他的?请继续往下看

GUI 与 Matplotlib

两张图

from matplotlib.figure import Figure
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
import tkinter as tk
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif']=['SimHei']    #画图时显示中文字体
plt.rcParams['axes.unicode_minus'] = False

fig = Figure(figsize=(12,8),facecolor='white')
# axis = fig.add_subplot(111)
axis = fig.add_subplot(211)
xValue = [1,2,3,4]
yValue = [5,7,6,8]
axis.plot(xValue,yValue)
axis.set_xlabel('我是x轴')
axis.set_ylabel('我是y轴')
# axis.grid()

axis.grid(linestyle='-')    #默认为虚线网格,设置实线网格

axis1 = fig.add_subplot(212)
xValue1 = [1,2,3,4]
yValue1 = [7,5,8,6]
axis1.plot(xValue1,yValue1)
axis1.grid()
axis1.set_xlabel('我是x周')
axis1.set_ylabel('我是y轴')


def _destroyWindow():
    root.quit()
    root.destroy()
    
root = tk.Tk()
root.withdraw()
root.protocol('WM_DELETE_WINDOW',_destroyWindow)

canvas = FigureCanvasTkAgg(fig,master=root)
canvas._tkcanvas.pack(side='top',fill=tk.BOTH,expand=1)

root.update()
root.deiconify()
root.mainloop()

上面画了两张图,大家可以尝试着运行一下,这里就不展示结果了。

缩放、legend

缩放可以通过 fig = Figure(figsize=(12,5)),这一句修改。只要修改参数 figsize 即可。

legend 的显示与 plt 画图类似,直接在 axis.plot 中加入 label 参数,再用 axis.legend 接口即可,代码如下:

from matplotlib.figure import Figure
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
import tkinter as tk
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif']=['SimHei']    #画图时显示中文字体
plt.rcParams['axes.unicode_minus'] = False

fig = Figure(figsize=(10,8),facecolor='white')
axis = fig.add_subplot(111)
xValue = [1,2,3,4]
yValue1 = [5,7,6,8]
yValue2 = [5.5,6.6,7.7,8.8]
yValue3 = [8,7,6,5]
axis.plot(xValue,yValue1,label='曲线1')
axis.plot(xValue,yValue2,label='曲线2')
axis.plot(xValue,yValue3,label='曲线3')
axis.set_xlabel('我是x轴')
axis.set_ylabel('我是y轴')
axis.legend(loc='upper right')

axis.grid(linestyle='-')    #默认为虚线网格,设置实线网格

def _destroyWindow():
    root.quit()
    root.destroy()
    
root = tk.Tk()
root.withdraw()
root.protocol('WM_DELETE_WINDOW',_destroyWindow)

canvas = FigureCanvasTkAgg(fig,master=root)
canvas._tkcanvas.pack(side='top',fill=tk.BOTH,expand=1)

root.update()
root.deiconify()
root.mainloop()

在这里插入图片描述

动态调整显示范围

我们修改 yValue2 参数,把他弄成很大很大,如下所示:
在这里插入图片描述
可以看到,我们很难看出其余两条线的走向了。因此,我们需要动态地调整显示范围,以便能够更好地显示其他曲线的细节。

调整显示范围的办法很简单,只要两行代码
axis.set_xlim(1,4) axis.set_ylim(5,10)

但是如何动态调整呢?这就要下点功夫了。首先定义一个阀值 Y_MAX,之后:

......
yAll = [yValue1,yValue2,yValue3]
Y_MAX = 20
miny = min([y for yValue in yAll for y in yValue])
maxy = max([y for yValue in yAll for y in yValue if y < Y_MAX])
axis.set_ylim(miny,maxy)
......

之后:
在这里插入图片描述

总结

按照惯例,来一个总结吧。本章是最简单的一章了吧,大家也不要去记忆代码,只需要在用到的时候,还记得有一位叫 zhuo木鸟的 CSDN 博主就行了。

现在,我们的 GUI 已经基本完善了。接下来,我们要完善他的运行性能,怎么完善?见下一章:Python GUI:Tkinter——06

猜你喜欢

转载自blog.csdn.net/weixin_42141390/article/details/106516423