2025, Nov 30 00:01
Как добавить кнопку экспорта CSV в панель Matplotlib (TkAgg, Tool Manager)
Пошагово показываем, как добавить кнопку экспорта CSV в панель инструментов Matplotlib с бэкендом TkAgg: Tool Manager, собственный ToolBase и готовый пример кода.
Встраивать собственное действие в панель инструментов Matplotlib часто необходимо, когда нужен единый и понятный интерфейс для экспорта графиков. Обычный первый шаг — добавить виджет Button прямо на саму фигуру. Это работает, но такой элемент лежит поверх холста, а не рядом со штатными кнопками панели, вроде значка-дискеты “Save the figure”. Если вы используете бэкенд TkAgg, поместить свой элемент именно в панель помогает API диспетчера инструментов (Tool Manager).
Минимальный пример: кнопка на холсте, а не в панели инструментов
import matplotlib.pyplot as plt
from matplotlib.widgets import Button
import csv
xs = [1, 2, 3, 4, 5]
ys = [2, 3, 5, 7, 11]
def write_csv(evt):
out_path = 'data.csv'
with open(out_path, 'w', newline='') as fh:
csvw = csv.writer(fh)
csvw.writerow(['X', 'Y'])
csvw.writerows(zip(xs, ys))
print(f'Data saved to {out_path}')
fig_obj, axis_obj = plt.subplots()
plt.plot(xs, ys, linestyle='None', marker='.', markersize=5)
plt.subplots_adjust(bottom=0.2)
btn_axes = plt.axes([0.81, 0.05, 0.1, 0.075])
btn_widget = Button(btn_axes, 'Save CSV')
btn_widget.on_clicked(write_csv)
plt.show()Что здесь происходит на самом деле
Приведённый код добавляет кнопку как отрисованный элемент интерфейса, а не как действие панели. Чтобы разместить кнопку среди штатных элементов панели, нужно перейти на систему Tool Manager. Механизм следующий: создаём собственный инструмент на основе ToolBase, регистрируем его в toolmanager у фигуры и затем добавляем в одну из групп панели. В случае TkAgg это работает, если включить вариант панели toolmanager и зарегистрировать инструмент.
Решение: создать подкласс ToolBase и зарегистрировать его в панели инструментов
Последовательность действий простая. Убедитесь, что выбран TkAgg, переключите реализацию панели на toolmanager, реализуйте подкласс ToolBase, в котором trigger вызывает вашу функцию экспорта в CSV, и добавьте его в панель. Расположение контролируется выбранной группой и индексом. Группа 'io' с позицией 1 помещает кнопку среди инструментов ввода-вывода; группа 'navigation' с позицией -1 — в блок навигации. Полный пример ниже связывает всё вместе.
import matplotlib
matplotlib.use('TkAgg')
import matplotlib.pyplot as plt
import csv
from matplotlib.backend_tools import ToolBase
plt.rcParams['toolbar'] = 'toolmanager'
class CsvExportTool(ToolBase):
def trigger(self, *args, **kwargs):
write_csv(None)
def write_csv(evt):
out_path = 'data.csv'
with open(out_path, 'w', newline='') as fh:
csvw = csv.writer(fh)
csvw.writerow(['X', 'Y'])
csvw.writerows(zip(xs, ys))
print(f'Data saved to {out_path}')
xs = [1, 2, 3, 4, 5]
ys = [2, 3, 5, 7, 11]
fig_obj, axis_obj = plt.subplots()
plt.plot(xs, ys, linestyle='None', marker='.', markersize=5)
plt.subplots_adjust(bottom=0.2)
fig_obj.canvas.manager.toolmanager.add_tool('Save as CSV', CsvExportTool)
fig_obj.canvas.manager.toolbar.add_tool('Save as CSV', 'io', 1)
plt.show()Если нужно иное место, зарегистрируйте инструмент в группе 'navigation' и задайте индекс, например -1, чтобы позиционировать его относительно существующих средств навигации. Имя группы и позиция определяют, где именно кнопка появится на панели.
Зачем это нужно
Размещение действий экспорта на панели инструментов согласует ваши доработки с привычным для пользователя интерфейсом и не загромождает область построения. Кроме того, это обеспечивает доступность действия в тех бэкендах, которые поддерживают Tool Manager, с поведением, сопоставимым со штатными элементами вроде “Save the figure”. Для процессов, где экспорт данных — ключевая операция, такая согласованность снижает трение.
Итоги
Если требуется кнопка на панели в TkAgg, используйте API Tool Manager, а не рисуйте Button на холсте. Наследуйтесь от ToolBase, установите для панели режим toolmanager и зарегистрируйте инструмент в нужной группе, указав индекс для позиционирования. Для действий ввода-вывода группа 'io' с небольшим положительным индексом размещает элемент рядом со значком сохранения; для навигации альтернативой будет группа 'navigation' с отрицательным индексом. Если вы встраиваете Matplotlib в приложение на tkinter, существует и другой путь — через NavigationToolbar2TkAgg, который позволяет менять состав панели, но описанный выше шаблон охватывает чистую конфигурацию Matplotlib с TkAgg.