@@ -453,7 +453,9 @@ def print_raw(self, filename_or_obj, *args, **kwargs):
453
453
454
454
print_rgba = print_raw
455
455
456
- def print_png (self , filename_or_obj , * args , ** kwargs ):
456
+ def print_png (self , filename_or_obj , * args ,
457
+ metadata = None , pil_kwargs = None ,
458
+ ** kwargs ):
457
459
"""
458
460
Write the figure to a PNG file.
459
461
@@ -494,21 +496,45 @@ def print_png(self, filename_or_obj, *args, **kwargs):
494
496
.. _PNG specification: \
495
497
https://www.w3.org/TR/2003/REC-PNG-20031110/#11keywords
496
498
499
+ pil_kwargs : dict, optional
500
+ If set to a non-None value, use Pillow to save the figure instead
501
+ of Matplotlib's builtin PNG support, and pass these keyword
502
+ arguments to `PIL.Image.save`.
503
+
504
+ If the 'pnginfo' key is present, it completely overrides
505
+ *metadata*, including the default 'Software' key.
497
506
"""
498
- FigureCanvasAgg .draw (self )
499
- renderer = self .get_renderer ()
500
507
501
- version_str = (
502
- 'matplotlib version ' + __version__ + ', http://matplotlib.org/' )
503
- metadata = OrderedDict ({'Software' : version_str })
504
- user_metadata = kwargs .pop ("metadata" , None )
505
- if user_metadata is not None :
506
- metadata .update (user_metadata )
508
+ if metadata is None :
509
+ metadata = {}
510
+ metadata = {
511
+ "Software" :
512
+ f"matplotlib version{ __version__ } , http://matplotlib.org/" ,
513
+ ** metadata ,
514
+ }
507
515
508
- with cbook ._setattr_cm (renderer , dpi = self .figure .dpi ), \
509
- cbook .open_file_cm (filename_or_obj , "wb" ) as fh :
510
- _png .write_png (renderer ._renderer , fh ,
511
- self .figure .dpi , metadata = metadata )
516
+ if pil_kwargs is not None :
517
+ from PIL import Image
518
+ from PIL .PngImagePlugin import PngInfo
519
+ buf , size = self .print_to_buffer ()
520
+ # Only use the metadata kwarg if pnginfo is not set, because the
521
+ # semantics of duplicate keys in pnginfo is unclear.
522
+ if "pnginfo" not in pil_kwargs :
523
+ pnginfo = PngInfo ()
524
+ for k , v in metadata .items ():
525
+ pnginfo .add_text (k , v )
526
+ pil_kwargs ["pnginfo" ] = pnginfo
527
+ pil_kwargs .setdefault ("dpi" , (self .figure .dpi , self .figure .dpi ))
528
+ (Image .frombuffer ("RGBA" , size , buf , "raw" , "RGBA" , 0 , 1 )
529
+ .save (filename_or_obj , format = "png" , ** pil_kwargs ))
530
+
531
+ else :
532
+ FigureCanvasAgg .draw (self )
533
+ renderer = self .get_renderer ()
534
+ with cbook ._setattr_cm (renderer , dpi = self .figure .dpi ), \
535
+ cbook .open_file_cm (filename_or_obj , "wb" ) as fh :
536
+ _png .write_png (renderer ._renderer , fh ,
537
+ self .figure .dpi , metadata = metadata )
512
538
513
539
def print_to_buffer (self ):
514
540
FigureCanvasAgg .draw (self )
0 commit comments