Skip to content

Commit

Permalink
Merge pull request #1975 from pwuertz/pgf_mixedrenderer
Browse files Browse the repository at this point in the history
MixedModeRenderer non-72-dpi fixes & Pgf mixed rendering
  • Loading branch information
pwuertz authored and mdboom committed May 28, 2013
1 parent b093b8c commit ca293ce
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 15 deletions.
12 changes: 8 additions & 4 deletions lib/matplotlib/backends/backend_mixed.py
Expand Up @@ -48,6 +48,7 @@ def __init__(self, figure, width, height, dpi, vector_renderer,
# the figure dpi before and after the rasterization. Although
# this looks ugly, I couldn't find a better solution. -JJL
self.figure=figure
self._figdpi = figure.get_dpi()

self._bbox_inches_restore = bbox_inches_restore

Expand Down Expand Up @@ -121,16 +122,19 @@ def stop_rasterizing(self):
image.is_grayscale = False
image.flipud_out()
gc = self._renderer.new_gc()
# TODO: If the mixedmode resolution differs from the figure's
# dpi, the image must be scaled (dpi->_figdpi). Not all
# backends support this.
self._renderer.draw_image(
gc,
float(l)/self.dpi*72.,
(float(height) - b - h)/self.dpi*72.,
float(l) / self.dpi * self._figdpi,
(float(height)-b-h) / self.dpi * self._figdpi,
image)
self._raster_renderer = None
self._rasterizing = False

# restore the figure dpi.
self.figure.set_dpi(72)
# restore the figure dpi.
self.figure.set_dpi(self._figdpi)

if self._bbox_inches_restore: # when tight bbox is used
r = process_figure_for_rasterizing(self.figure,
Expand Down
27 changes: 16 additions & 11 deletions lib/matplotlib/backends/backend_pgf.py
Expand Up @@ -13,6 +13,7 @@
import matplotlib as mpl
from matplotlib.backend_bases import RendererBase, GraphicsContextBase,\
FigureManagerBase, FigureCanvasBase
from matplotlib.backends.backend_mixed import MixedModeRenderer
from matplotlib.figure import Figure
from matplotlib.text import Text
from matplotlib.path import Path
Expand Down Expand Up @@ -738,7 +739,7 @@ def __init__(self, *args):
def get_default_filetype(self):
return 'pdf'

def _print_pgf_to_fh(self, fh):
def _print_pgf_to_fh(self, fh, *args, **kwargs):
header_text = r"""%% Creator: Matplotlib, PGF backend
%%
%% To include the figure in your LaTeX document, write
Expand Down Expand Up @@ -767,6 +768,7 @@ def _print_pgf_to_fh(self, fh):

# get figure size in inch
w, h = self.figure.get_figwidth(), self.figure.get_figheight()
dpi = self.figure.get_dpi()

# create pgfpicture environment and write the pgf code
fh.write(header_text)
Expand All @@ -777,7 +779,10 @@ def _print_pgf_to_fh(self, fh):
writeln(fh, r"\begin{pgfpicture}")
writeln(fh, r"\pgfpathrectangle{\pgfpointorigin}{\pgfqpoint{%fin}{%fin}}" % (w, h))
writeln(fh, r"\pgfusepath{use as bounding box}")
renderer = RendererPgf(self.figure, fh)
_bbox_inches_restore = kwargs.pop("bbox_inches_restore", None)
renderer = MixedModeRenderer(self.figure, w, h, dpi,
RendererPgf(self.figure, fh),
bbox_inches_restore=_bbox_inches_restore)
self.figure.draw(renderer)

# end the pgfpicture environment
Expand All @@ -796,14 +801,14 @@ def print_pgf(self, fname_or_fh, *args, **kwargs):
# figure out where the pgf is to be written to
if is_string_like(fname_or_fh):
with codecs.open(fname_or_fh, "w", encoding="utf-8") as fh:
self._print_pgf_to_fh(fh)
self._print_pgf_to_fh(fh, *args, **kwargs)
elif is_writable_file_like(fname_or_fh):
raise ValueError("saving pgf to a stream is not supported, " +
"consider using the pdf option of the pgf-backend")
else:
raise ValueError("filename must be a path")

def _print_pdf_to_fh(self, fh):
def _print_pdf_to_fh(self, fh, *args, **kwargs):
w, h = self.figure.get_figwidth(), self.figure.get_figheight()

try:
Expand All @@ -814,7 +819,7 @@ def _print_pdf_to_fh(self, fh):
fname_pdf = os.path.join(tmpdir, "figure.pdf")

# print figure to pgf and compile it with latex
self.print_pgf(fname_pgf)
self.print_pgf(fname_pgf, *args, **kwargs)

latex_preamble = get_preamble()
latex_fontspec = get_fontspec()
Expand Down Expand Up @@ -856,13 +861,13 @@ def print_pdf(self, fname_or_fh, *args, **kwargs):
# figure out where the pdf is to be written to
if is_string_like(fname_or_fh):
with open(fname_or_fh, "wb") as fh:
self._print_pdf_to_fh(fh)
self._print_pdf_to_fh(fh, *args, **kwargs)
elif is_writable_file_like(fname_or_fh):
self._print_pdf_to_fh(fname_or_fh)
self._print_pdf_to_fh(fname_or_fh, *args, **kwargs)
else:
raise ValueError("filename must be a path or a file-like object")

def _print_png_to_fh(self, fh):
def _print_png_to_fh(self, fh, *args, **kwargs):
converter = make_pdf_to_png_converter()

try:
Expand All @@ -871,7 +876,7 @@ def _print_png_to_fh(self, fh):
fname_pdf = os.path.join(tmpdir, "figure.pdf")
fname_png = os.path.join(tmpdir, "figure.png")
# create pdf and try to convert it to png
self.print_pdf(fname_pdf)
self.print_pdf(fname_pdf, *args, **kwargs)
converter(fname_pdf, fname_png, dpi=self.figure.dpi)
# copy file contents to target
with open(fname_png, "rb") as fh_src:
Expand All @@ -888,9 +893,9 @@ def print_png(self, fname_or_fh, *args, **kwargs):
"""
if is_string_like(fname_or_fh):
with open(fname_or_fh, "wb") as fh:
self._print_png_to_fh(fh)
self._print_png_to_fh(fh, *args, **kwargs)
elif is_writable_file_like(fname_or_fh):
self._print_png_to_fh(fname_or_fh)
self._print_png_to_fh(fname_or_fh, *args, **kwargs)
else:
raise ValueError("filename must be a path or a file-like object")

Expand Down
Binary file not shown.
12 changes: 12 additions & 0 deletions lib/matplotlib/tests/test_backend_pgf.py
Expand Up @@ -145,6 +145,18 @@ def test_pathclip():
plt.savefig(os.path.join(result_dir, "pgf_pathclip.pdf"))


# test mixed mode rendering
@switch_backend('pgf')
def test_mixedmode():
if not check_for('xelatex'):
raise SkipTest('xelatex + pgf is required')

Y, X = np.ogrid[-1:1:40j, -1:1:40j]
plt.figure()
plt.pcolor(X**2 + Y**2).set_rasterized(True)
compare_figure('pgf_mixedmode.pdf')


if __name__ == '__main__':
import nose
nose.runmodule(argv=['-s','--with-doctest'], exit=False)

0 comments on commit ca293ce

Please sign in to comment.