This works to add a "Save as CSV" button in a Matplotlib plot:
import matplotlib.pyplot as plt
from matplotlib.widgets import Button
import csv
X = [1, 2, 3, 4, 5]
Y = [2, 3, 5, 7, 11]
def save_as_csv(event):
file_path = 'data.csv'
with open(file_path, 'w', newline='') as file:
writer = csv.writer(file)
writer.writerow(['X', 'Y'])
writer.writerows(zip(X, Y))
print(f'Data saved to {file_path}')
fig, ax = plt.subplots()
plt.plot(X, Y, linestyle='None', marker='.', markersize=5)
plt.subplots_adjust(bottom=0.2)
ax_button = plt.axes([0.81, 0.05, 0.1, 0.075])
button = Button(ax_button, 'Save CSV')
button.on_clicked(save_as_csv)
plt.show()
How to have the button in the toolbar, next to the "Save the figure" (diskette icon), with TkAgg
backend?
Based on documentation Tool Manager — Matplotlib:
it needs to create custom class based on ToolBase
from matplotlib.backend_tools import ToolBase
plt.rcParams['toolbar'] = 'toolmanager'
class SaveCSVTool(ToolBase):
def trigger(self, *args, **kwargs):
save_as_csv(None) # <-- execute your original function
and add it to toolmanager and toolbar with
fig.canvas.manager.toolmanager.add_tool('Save as CSV', SaveCSVTool)
fig.canvas.manager.toolbar.add_tool('Save as CSV', 'io', 1)
Position for 'navigation', -1
:
Position for 'io', 1
:
Other groups in toolbar
(I asked ChatGTP
for groups because I couldn't find it in documetation but I didn't check if work)
"navigation" Tools for navigation (pan, zoom, home, back, forward).
"toolgroup" Used for mutually exclusive tools (e.g., toggle tools like pan/zoom).
"default" Default group for tools that don’t specify a group.
"io" Tools related to saving/exporting (e.g., save button).
"zoompan" Pan and zoom tools (can overlap with "navigation").
"none" Tools that should not be grouped or float independently.
(finally I found some of them in source code)
Full working code:
import matplotlib
matplotlib.use('TkAgg') # to makes sure it uses `TkAgg` instead of `TkQt`
import matplotlib.pyplot as plt
#from matplotlib.widgets import Button
import csv
from matplotlib.backend_tools import ToolBase #, ToolToggleBase
plt.rcParams['toolbar'] = 'toolmanager'
# --- classes ---
class SaveCSVTool(ToolBase):
#default_keymap = 'c' # keyboard shortcut
#description = 'Save As CSV'
#image = r'C:\path\to\image.png'
#image = 'mpl-data/images/filesave' # this is path from button `Save the figure` but it doesn't works for me in custon button
#image = 'filesave.png` # this works for me but show warning that it is deprecated
def trigger(self, *args, **kwargs):
save_as_csv(None)
# --- functions ---
def save_as_csv(event):
file_path = 'data.csv'
with open(file_path, 'w', newline='') as file:
writer = csv.writer(file)
writer.writerow(['X', 'Y'])
writer.writerows(zip(X, Y))
print(f'Data saved to {file_path}')
# --- main ---
X = [1, 2, 3, 4, 5]
Y = [2, 3, 5, 7, 11]
fig, ax = plt.subplots()
plt.plot(X, Y, linestyle='None', marker='.', markersize=5)
plt.subplots_adjust(bottom=0.2)
#ax_button = plt.axes([0.81, 0.05, 0.1, 0.075])
#button = Button(ax_button, 'Save CSV')
#button.on_clicked(save_as_csv)
fig.canvas.manager.toolmanager.add_tool('Save as CSV', SaveCSVTool)
fig.canvas.manager.toolbar.add_tool('Save as CSV', 'io', 1)
plt.show()