Description
I'm currently trying to figure out the best way to unify the figures for my thesis, and intend to use the PGF backend to directly \include
figures in my LaTeX document.
When creating PGF figures that include raster graphics (e.g., via imshow
), the graphic gets stored as a PNG file and imported via \pgfimage
, which is great. Unfortunately, it doesn't support interpolation='none'
as the PDF backend does:
import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt
np.random.seed(42)
data = np.random.randn(5,6)
plt.imshow(data, cmap='hot', interpolation='none')
plt.savefig('test.pdf')
mpl.rcParams['pgf.texsystem'] = 'pdflatex'
plt.savefig('test.pgf')
Checking the created PDF file in Evince, it indeed includes a PNG graphic of 5x6 pixels. The graphic for the PGF file is blown up, though:
$ file test-img0.png
test-img0.png: PNG image data, 577 x 481, 8-bit/color RGBA, non-interlaced
I can manually fix this by replacing it with a 5x6 PNG file and tweaking the PGF output as follows:
59c59
< \pgftext[at=\pgfqpoint{1.220000in}{0.600000in},left,bottom]{\pgfimage[interpolate=true,width=5.770000in,height=4.810000in]{test-img0.png}}%
---
> \pgftext[at=\pgfqpoint{1.220000in}{0.600000in},left,bottom]{\pgfimage[interpolate=false,width=5.770000in,height=4.810000in]{test-img0.png}}%
Can we modify the PGF backend such that it emits the unscaled raster graphic and uses interpolate=false
?
I'm willing to work on this myself, but would appreciate some guidance. Looking through the code, the image is written in https://github.com/matplotlib/matplotlib/blob/f1bab50/lib/matplotlib/backends/backend_pgf.py#L612.
The corresponding code in the PDF backend starts at https://github.com/matplotlib/matplotlib/blob/f1bab50/lib/matplotlib/backends/backend_pdf.py#L1600.
It overrides the option_scale_image()
function to return True
, and it takes an additional transform
parameter in draw_image()
. I guess this is where the magic happens -- if there's a transformation to apply, it will get the unmodified image and construct the PDF so the image is scaled appropriately.
The documentation on that parameter is scarce (https://github.com/matplotlib/matplotlib/blob/f1bab50/lib/matplotlib/backend_bases.py#L511), but it seems you can convert it into six values giving an affine transformation.
If I want the PGF backend to handle scaling, will the backend have to handle the full range of possible affine transformations (scaling would suffice for me)? Is the transform
guaranteed to only be used for interpolation='none'
, so I can set interpolate=false
in this case? Is there any better documentation on the transform
?