4
4
import logging
5
5
import math
6
6
import os .path
7
+ import pathlib
7
8
import sys
8
9
import tkinter as tk
9
10
import tkinter .filedialog
@@ -499,11 +500,8 @@ def create_with_canvas(cls, canvas_class, figure, num):
499
500
'images/matplotlib_large.png' ))
500
501
icon_img_large = ImageTk .PhotoImage (
501
502
file = icon_fname_large , master = window )
502
- try :
503
- window .iconphoto (False , icon_img_large , icon_img )
504
- except Exception as exc :
505
- # log the failure (due e.g. to Tk version), but carry on
506
- _log .info ('Could not load matplotlib icon: %s' , exc )
503
+
504
+ window .iconphoto (False , icon_img_large , icon_img )
507
505
508
506
canvas = canvas_class (figure , master = window )
509
507
manager = cls (canvas , num , window )
@@ -846,15 +844,15 @@ def _Spacer(self):
846
844
return s
847
845
848
846
def save_figure (self , * args ):
849
- filetypes = self .canvas .get_supported_filetypes ().copy ()
850
- default_filetype = self .canvas .get_default_filetype ()
847
+ filetypes = self .canvas .get_supported_filetypes_grouped ()
848
+ tk_filetypes = [
849
+ (name , " " .join (f"*.{ ext } " for ext in exts ))
850
+ for name , exts in sorted (filetypes .items ())
851
+ ]
851
852
852
- # Tk doesn't provide a way to choose a default filetype,
853
- # so we just have to put it first
854
- default_filetype_name = filetypes .pop (default_filetype )
855
- sorted_filetypes = ([(default_filetype , default_filetype_name )]
856
- + sorted (filetypes .items ()))
857
- tk_filetypes = [(name , '*.%s' % ext ) for ext , name in sorted_filetypes ]
853
+ default_extension = self .canvas .get_default_filetype ()
854
+ default_filetype = self .canvas .get_supported_filetypes ()[default_extension ]
855
+ filetype_variable = tk .StringVar (self , default_filetype )
858
856
859
857
# adding a default extension seems to break the
860
858
# asksaveasfilename dialog when you choose various save types
@@ -863,14 +861,18 @@ def save_figure(self, *args):
863
861
# defaultextension = self.canvas.get_default_filetype()
864
862
defaultextension = ''
865
863
initialdir = os .path .expanduser (mpl .rcParams ['savefig.directory' ])
866
- initialfile = self .canvas .get_default_filename ()
864
+ # get_default_filename() contains the default extension. On some platforms,
865
+ # choosing a different extension from the dropdown does not overwrite it,
866
+ # so we need to remove it to make the dropdown functional.
867
+ initialfile = pathlib .Path (self .canvas .get_default_filename ()).stem
867
868
fname = tkinter .filedialog .asksaveasfilename (
868
869
master = self .canvas .get_tk_widget ().master ,
869
870
title = 'Save the figure' ,
870
871
filetypes = tk_filetypes ,
871
872
defaultextension = defaultextension ,
872
873
initialdir = initialdir ,
873
874
initialfile = initialfile ,
875
+ typevariable = filetype_variable
874
876
)
875
877
876
878
if fname in ["" , ()]:
@@ -879,9 +881,16 @@ def save_figure(self, *args):
879
881
if initialdir != "" :
880
882
mpl .rcParams ['savefig.directory' ] = (
881
883
os .path .dirname (str (fname )))
884
+
885
+ # If the filename contains an extension, let savefig() infer the file
886
+ # format from that. If it does not, use the selected dropdown option.
887
+ if pathlib .Path (fname ).suffix [1 :] != "" :
888
+ extension = None
889
+ else :
890
+ extension = filetypes [filetype_variable .get ()][0 ]
891
+
882
892
try :
883
- # This method will handle the delegation to the correct type
884
- self .canvas .figure .savefig (fname )
893
+ self .canvas .figure .savefig (fname , format = extension )
885
894
except Exception as e :
886
895
tkinter .messagebox .showerror ("Error saving file" , str (e ))
887
896
0 commit comments