Skip to content

Instantly share code, notes, and snippets.

@constructor-s
Last active May 29, 2021 04:33
Show Gist options
  • Save constructor-s/006ba449fe0de19903aaf6f843ab450a to your computer and use it in GitHub Desktop.
Save constructor-s/006ba449fe0de19903aaf6f843ab450a to your computer and use it in GitHub Desktop.
Quick preview and export of Matplotlib Figure pickles
call conda activate
python mpl_deserialize.py %1 --preview
import PIL
from argparse import ArgumentParser
from pathlib import Path
import logging
import sys
import pickle
import tempfile
from io import BytesIO
import os
import subprocess
_logger = logging.getLogger(__name__)
parser = ArgumentParser("Viewer and savefig CLI for pickled matplotlib Figure")
parser.add_argument("file", nargs="?", default="", help="The pickle file containing matplotlib Figure handle")
parser.add_argument("--preview", action="store_true", help="Preview a PNG render of the figure")
parser.add_argument("--dpi", required=False, type=int, default=144, help="Default preview DPI")
parser.add_argument("--output", required=False, default=None, help="Export image file")
args = parser.parse_args()
if not args.file:
_logger.warning("No file specified")
sys.exit()
file = Path(args.file)
if not file.exists():
_logger.warning("%s does not exist", file)
sys.exit()
with open(file, "rb") as f:
fig = pickle.load(f)
fig.set_dpi(args.dpi) # Need to use this for appropriate canvas size later
if args.preview:
bio = BytesIO()
fig.savefig(bio, format="rgba", dpi=fig.dpi)
im = PIL.Image.frombuffer(mode='RGBA', size=fig.canvas.get_width_height(), data=bio.getbuffer())
im.show(title=file.absolute())
out_filename = args.output
if out_filename is None:
print("Please enter output filename, or leave empty to exit:")
out_filename = input(">> ")
if any([out_filename.lower().endswith(suffix) for suffix in (".png", ".jpg", ".jpeg", ".tif", ".tiff")]):
print("Please enter desired dpi:")
try:
dpi = int(input(">> "))
fig.set_dpi(dpi)
except ValueError:
pass
if out_filename == "":
print("Exit")
else:
if out_filename.lower().endswith("emf"):
# EMF conversion using inkscape
svg_bio = BytesIO()
fig.savefig(svg_bio, format="svg")
svg_bio.seek(0)
# https://superuser.com/a/1579739/756769
# Inkscape 1.0.1
_logger.info("Using Inkscape to convert SVG to EMF")
result = subprocess.run(["inkscape", "--pipe", "--export-filename", out_filename], input=svg_bio.read())
_logger.info("SVG to EMF conversion: %s", result)
elif any([out_filename.lower().endswith(suffix) for suffix in (".tif", ".tiff")]):
fig.savefig(out_filename, dpi=fig.dpi, pil_kwargs={"compression": "tiff_lzw"})
else:
fig.savefig(out_filename, dpi=fig.dpi)
print("Starting:", Path(out_filename).absolute())
os.startfile(out_filename)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment