На этом шаге мы рассмотрим пример построения графиков.
Рассмотрим пример построения графиков функций с использованием виджета Canvas.
Создадим окно заданного размера и установим на нем виджет Notebook. Он представляет собой набор окон, которые имеют закладки. Щелчок мыши по одной из закладок открывает соответствующее окно. Для работы с виджетом Notebook следует импортировать модуль tkinter.ttk.
На закладках виджета Notebook разместим холсты Canvas. На первом холсте нарисуем график функции y=sin(x). На втором - график функции y=sin(x)/x . На третьем - график функции y= x*exp(-x2). Вид трех закладок показан на рисунке 1.
Рис.1. Результат работы приложения
Ниже приведен код примера и даны пояснения.
from tkinter import * from tkinter.ttk import * import math def makecanvas(txt, bgclr): # добавление панелиNotebook с холстом cnvs=Canvas(nb, background=bgclr) nb.add(cnvs, text=txt, padding=3) return cnvs # ===================================================== # функция построения на объекте холста canvas графика непрерывной # функции fun. График строится на отрезке [a, b], # kx,ky - масштабные множители по осям # положение начала координат (0, 0) в точке холста (xo, yo) # аргумент exclude - список X координат исключаемых точек def drawFunc(canvas, fun, a, b, kx, ky, exclude=None): points = [] num = 500 # количество точек for n in range(num): x = a + (b - a) / num * n if exclude != None: if x in exclude: continue y = fun(x) # положительное направление оси Y вверх pp = (xo + kx * x, yo - ky * y) points.append(pp) # список пар (xi,yi) точек кривой canvas.create_line(points, fill="blue", smooth=0, width=3) # график xAxe = [(xo + a * kx, yo),(xo + b * kx, yo)] canvas.create_line(xAxe, fill="black", width=2) # ось X my = max([abs(e[1] - yo) for e in points])# максимальная амплитуда yAxe = [(xo, yo - my * 1.05), (xo, yo + my * 1.05)] canvas.create_line(yAxe, fill="black", width=2)# ось Y maxy = min([e[1] - yo for e in points]) gorMark = [(xo - 5,yo + maxy), (xo + 5, yo + maxy)] canvas.create_line(gorMark, fill="black", width=1)# засечка на оси Y # текстовая отметка на оси Y canvas.create_text(xo + 28, yo + maxy, text="{0:.3f}".format(-maxy / ky)) def g(x): return math.sin(x) / x def f(x): return x * math.exp(-x ** 2) root = Tk() root.title('Графики функций') nb = Notebook(width=480, height=360) nb.pack(expand=1, fill='both') # создание трех холстов на закладках виджета Notebook cnvs1 = makecanvas(' sin(x) ', '#f7ffff') cnvs2 = makecanvas(' sin(x)/x ' , '#fff7ff') cnvs3 = makecanvas(' x*exp(-x**2)', '#fffff7') # ============================================== # график функции sin(x) xo, yo = 20, 180 # экранное положение начала координат drawFunc(cnvs1, math.sin, 0, 12, 35, 150) # график функции sin(x)/x # исключить из рассмотрения точку x=0 xo, yo = 240, 180 # экранное положение начала координат drawFunc(cnvs2, g, -20, 20, 11, 150, [0]) # график функции x*exp(-x**2) xo, yo = 240, 180 # экранное положение начала координат drawFunc(cnvs3, f, -3, 3, 80, 350) root.mainloop()
Прокомментируем приведенный пример.
def makecanvas(txt, bgclr): # добавление панелиNotebook с холстом cnvs=Canvas(nb, background=bgclr) nb.add(cnvs, text=txt, padding=3) return cnvs . . . . # создание трех холстов на закладках виджета Notebook cnvs1 = makecanvas(' sin(x) ', '#f7ffff') cnvs2 = makecanvas(' sin(x)/x ' , '#fff7ff') cnvs3 = makecanvas(' x*exp(-x**2)', '#fffff7')
Обычно каждая панель Notebook состоит из контейнерного элемента, содержащего другие виджеты. В нашем примере таким контейнером является холст. Добавление новой панели с холстом выполняется методом
Notebook.add(canvas[, <Заголовок>, <Опции панели>]) .
Для управления панелями элемента Notebook имеется множество свойств и методов. В частности, к панели, открытой в данный момент, можно обратиться с помощью инструкции Notebook.selected().
Основной код построения графиков собран в функции drawFunc().
# ===================================================== # функция построения на объекте холста canvas графика непрерывной # функции fun. График строится на отрезке [a, b], # kx,ky - масштабные множители по осям # положение начала координат (0, 0) в точке холста (xo, yo) # аргумент exclude - список X координат исключаемых точек def drawFunc(canvas, fun, a, b, kx, ky, exclude=None): points = [] num = 500 # количество точек for n in range(num): x = a + (b - a) / num * n if exclude != None: if x in exclude: continue y = fun(x) # положительное направление оси Y вверх pp = (xo + kx * x, yo - ky * y) points.append(pp) # список пар (xi,yi) точек кривой canvas.create_line(points, fill="blue", smooth=0, width=3) # график xAxe = [(xo + a * kx, yo),(xo + b * kx, yo)] canvas.create_line(xAxe, fill="black", width=2) # ось X my = max([abs(e[1] - yo) for e in points])# максимальная амплитуда yAxe = [(xo, yo - my * 1.05), (xo, yo + my * 1.05)] canvas.create_line(yAxe, fill="black", width=2)# ось Y maxy = min([e[1] - yo for e in points]) gorMark = [(xo - 5,yo + maxy), (xo + 5, yo + maxy)] canvas.create_line(gorMark, fill="black", width=1)# засечка на оси Y # текстовая отметка на оси Y canvas.create_text(xo + 28, yo + maxy, text="{0:.3f}".format(-maxy / ky))
Завершает программу код, в котором функция drawFunc() вызывается три раза. Каждый раз функции передается идентификатор холста соответствующей панели и имя функции, график которой будет строиться. Перед вызовом задается точка холста (xo, yo), в которой будет располагаться начало координат нового графика.
. . . . . def g(x): return math.sin(x) / x def f(x): return x * math.exp(-x ** 2) . . . . . # ============================================== # график функции sin(x) xo, yo = 20, 180 # экранное положение начала координат drawFunc(cnvs1, math.sin, 0, 12, 35, 150) # график функции sin(x)/x # исключить из рассмотрения точку x=0 xo, yo = 240, 180 # экранное положение начала координат drawFunc(cnvs2, g, -20, 20, 11, 150, [0]) # график функции x*exp(-x**2) xo, yo = 240, 180 # экранное положение начала координат drawFunc(cnvs3, f, -3, 3, 80, 350)
На следующем шаге мы рассмотрим использование matplotlib в окнах tkinter.