Description
It looks like Pillow's png handling (which is hand-written https://github.com/python-pillow/Pillow/blob/master/src/PIL/PngImagePlugin.py, not based on libpng) is faster than matplotlib's, both for writing and for reading:
from time import perf_counter
import matplotlib as mpl; mpl.use("agg")
from matplotlib import pyplot as plt
import numpy as np
from PIL import Image
fig, ax = plt.subplots()
fig.canvas.draw()
t = np.asarray(fig.canvas.renderer._renderer)
for writer in ["mpl", "pil"]:
print(f"write with {writer}")
start = perf_counter()
for _ in range(100):
mpl.image.imsave("/tmp/test.png", t,
pil_kwargs={"mpl": None, "pil": {}}[writer])
print("write", perf_counter() - start)
start = perf_counter()
for _ in range(100):
mpl.image.imread("/tmp/test.png")
print("mpl read", perf_counter() - start)
start = perf_counter()
for _ in range(100):
with Image.open("/tmp/test.png") as image:
mpl.image.pil_to_array(image)
print("pil read", perf_counter() - start)
yields, for me:
write with mpl
write 1.5242545299988706
mpl read 0.9935761439992348
pil read 0.46841289500298444
write with pil
write 1.400021340996318
mpl read 0.9913013100012904
pil read 0.4612834110012045
#15160 reminded me that it's not always trivial to get C-level dependencies set up before building (though that specific issue is about freetype). We already vendor agg and qhull, and have an option to download freetype (via local_freetype/MPLLOCALFREETYPE), so the sole remaining dependency that always needs to be provided by the builder is libpng.
If we just depended (as an install_requires) on Pillow for png handling instead, we would be able to drop that dependency (together with a bunch of C code). Pillow has wheels for all three major OSes, supports PyPy, is actively developed, and has been around for a very long time.
Thoughts on making the switch?