I have been trying to save an imshow figure as a PDF, but when I try to open it up in my PDF reader (Acrobat Reader DC) it says "Insufficient data for an image" and refuses to display the image. Furthermore, if I open it in Google Chrome instead, I get an image, but it looks different from what it is supposed to. I use Spyder on a Windows computer, but I noticed that if I run the same code in the terminal, it works fine.
Here is an example:
plt.figure()
plt.imshow([[1,4,6],[6,7,8]])
plt.savefig("testplot.pdf")
plt.show()
This yields the following image in Spyder (the plt.imshow, not the saved image):
The saved image when opened in Google Chrome looks like this:
I use plt.savefig here, but I also tried plt.imsave, and in that case I can't even see it in Google Chrome.
Solution
Try updating your matplotlib version. The current version 3.10.1 should work.
python -m pip install -U matplotlib==3.10.1
Explanation
I could not find the corresponding PR in the release notes, but here's what my analysis gave.
Apparently there was a bug in the datastream generation of matplotlib, which did not occur for most regular images, but only for images with a low number of color values (<=16) that could therefore be encoded using a 4-bit color palette.
For some reason, matplotlib added one byte (=2 pixels) of unnecessary padding to each row, yielding the yellow line visible in Chrome that does not exist in the original data. Also, the row length was too long by one byte (=2 pixels) in every second row, resulting in the diagonals visible in Chrome.
Adobe Acrobat seems to recognize the size mismatch between the given height and width of the image object and the length of the datastream and gives the error "Insufficient data for an image", where "insufficient" seems to imply "too much" as well.
Hope this helps anyone else who encounters this issue.