Шаг 72.
Библиотека Tkinter. Компоненты и вспомогательные классы. Нестилизуемые компоненты. Компонент Canvas: графика matplotlib в окнах tkinter

    На этом шаге мы рассмотрим пример построения графика средствами matplotlib в окнах tkinter.

    Как показано в предыдущем шаге, модуль tkinter позволяет создавать приложения с оконным интерфейсом, содержащими векторную графику. В частности, использование графических функций виджета Canvas позволяет строить графики функций. Однако возможности модуля matplotlib значительно совершеннее, и желательно совмещать оконные приложения tkinter с графическими функциями matplotlib. Эта возможность реализована с помощью "составного" холста FigureCanvasTkAgg - специального класса, который наследует многие методы виджета Canvas, и добавляет возможности использования графических функций модуля matplotlib. Класс FigureCanvasTkAgg импортируется из модуля matplotlib.backends.backend_tkagg. Вместе с ним часто импортируется класс NavigationToolbar2Tk, который представляет собой панель управления графикой matplotlib. Она показана на рисунке 1 в этом шаге и обычно всегда присутствует в графических окнах matplotlib. Ее наличие в ваших окнах tkinter необязательно.

    В примере ниже приведен простой код, демонстрирующий встраивание графики matplotlib в программу с оконным интерфейсом. В нем реализовано построение график синусоиды средствами модуля matplotlib.pyplot в приложении tkinter.

import tkinter

from matplotlib.backends.backend_tkagg import (
    FigureCanvasTkAgg, NavigationToolbar2Tk)
from matplotlib.figure import Figure

import numpy as np


def _quit():
    root.quit()  # остановка цикла
    root.destroy()  # закрытие приложения


root = tkinter.Tk()
root.wm_title("Построение графика y=sin(x)")

fig = Figure(figsize=(5, 4), dpi=100)
t = np.linspace(0, 2 * np.pi)
ax = fig.add_subplot(111)
ax.plot(t, np.sin(t), '-rh', linewidth=3, markersize=5, markerfacecolor='b', 
     label=r'$\ y=sin(x) $')
ax.grid(color='b', linewidth=1.0)
ax.legend(fontsize=12)

canvas = FigureCanvasTkAgg(fig, master=root)
canvas.draw()
canvas.get_tk_widget().pack(side=tkinter.TOP, fill=tkinter.BOTH, expand=1)

toolbar = NavigationToolbar2Tk(canvas, root)
toolbar.update()
canvas.get_tk_widget().pack(side=tkinter.TOP, fill=tkinter.BOTH, expand=1)

button = tkinter.Button(master=root, text="Выход", command=_quit)
button.pack(side=tkinter.BOTTOM)

tkinter.mainloop()
Архив с файлом можно взять здесь.

    Результат выполнения программы приведен на рисунке 1.


Рис.1. Результат выполнения программы

    Прокомментируем проведенный текст примера.

    В первых строках кода программы выполняется импортирование необходимых модулей и функций. Следом за этим создается объект окна root и контейнерный элемент Frame, внутри которого мы позже разместим "составной" холст FigureCanvasTkAgg с графикой matplotlib.

    Строим график синусоиды функциями matplotlib.pyplot.

fig = Figure(figsize=(5, 4), dpi=100)
t = np.linspace(0, 2 * np.pi)
ax = fig.add_subplot(111)
ax.plot(t, np.sin(t), '-rh', linewidth=3, markersize=5, markerfacecolor='b', 
     label=r'$\ y=sin(x) $')
ax.grid(color='b', linewidth=1.0)
ax.legend(fontsize=12)

    Инструкцией

fig = Figure(figsize=(5, 4), dpi=100)
создается объект рисунка и в нем инструкцией
ax = fig.add_subplot(111)
создается графическая область Axes. Обратите внимание на параметр, который мы передаем 111 - это первая строка, первый столбец и первая (единственная) ячейка на сетке Figure. Кстати, Axes должна принадлежать только одной области Figure. Как правило, всегда сначала создается область Figure, а затем с помощью add_subplot() в Figure размещается одна или несколько областей Axes.

    Метод grid() добавляет сетку с указаннымир параметрами, а legend() - легенду.

    В графической области функциями модуля matplotlib.pyplot рисуется график (или несколько графиков). Инструкция

canvas = FigureCanvasTkAgg(fig, master=root)
создает объект класса "составного" холста FigureCanvasTkAgg. Его конструктор в качестве первого аргумента принимает ссылку на объект рисунка Figure, использованного при создании графики matplotlib. С помощью опции master=root задается родительски виджет (в нашем случае окно приложения), в котором будет находиться "составной" холст. В результате устанавливается "связь" между графическим окном fig (размещенным в памяти) и холстом, размещенным внутри окна приложения. После этого метод draw() "составного" холста включает отображение графики matplotlib.

    Нам остается корректно разместить холст внутри окна приложения. Метод canvas.get_tk_widget()

canvas.get_tk_widget().pack(side=tkinter.TOP, fill=tkinter.BOTH, expand=1)
возращает ссылку на объект "стандартного" холста Canvas, лежащего "в основании" класса составного холста. Полученная ссылка canvas используется при размещения холста упаковщиком pack().

    В завершении мы добавляем стандартную панель с кнопками управления matplotlib графикой.

toolbar = NavigationToolbar2Tk(canvas, root)
toolbar.update()
canvas.get_tk_widget().pack(side=tkinter.TOP, fill=tkinter.BOTH, expand=1)

    Добавляем кнопку для выхода из приложения, которую связываем с функцией _quit(), реализующей выход из приложения.

button = tkinter.Button(master=root, text="Выход", command=_quit)

    Оставшиеся две инструкции программы размещают контейнер - рамку внутри главного окна и запускают цикл обработки сообщений.

button.pack(side=tkinter.BOTTOM)

tkinter.mainloop()

    На следующем шаге мы продолжим изучение этого вопроса.




Предыдущий шаг Содержание Следующий шаг