>From cb1aa376c8aa0e7d977174b53fd72b7fd6badfb5 Mon Sep 17 00:00:00 2001
From: Michael Welter <mwelter@...1091...>
Date: Sun, 26 Aug 2012 17:18:08 +0200
Subject: [PATCH 2/2] fix: dpi setting should work now for rasterization in svg backend

---
 lib/matplotlib/backends/backend_svg.py |   33 ++++++++++++++++++++-----------
 lib/matplotlib/tests/test_image.py     |   27 ++++++++++++++++++++++++++
 2 files changed, 48 insertions(+), 12 deletions(-)

diff --git a/lib/matplotlib/backends/backend_svg.py b/lib/matplotlib/backends/backend_svg.py
index 0b9b7ab..f1c709c 100644
--- a/lib/matplotlib/backends/backend_svg.py
+++ b/lib/matplotlib/backends/backend_svg.py
@@ -244,10 +244,11 @@ class RendererSVG(RendererBase):
     FONT_SCALE = 100.0
     fontd = maxdict(50)
 
-    def __init__(self, width, height, svgwriter, basename=None):
+    def __init__(self, width, height, image_dpi, svgwriter, basename=None):
         self.width = width
         self.height = height
         self.writer = XMLWriter(svgwriter)
+        self.image_dpi = image_dpi # the actual dpi we want to rasterize stuff with
 
         self._groupd = {}
         if not rcParams['svg.image_inline']:
@@ -733,6 +734,11 @@ class RendererSVG(RendererBase):
     def option_scale_image(self):
         return True
 
+
+    def get_image_magnification(self):
+        return self.image_dpi/72.0
+        
+
     def draw_image(self, gc, x, y, im, dx=None, dy=None, transform=None):
         attrib = {}
         clipid = self._get_clip(gc)
@@ -755,6 +761,17 @@ class RendererSVG(RendererBase):
             im.resize(numcols, numrows)
 
         h,w = im.get_size_out()
+
+        if dx is None:
+            w = 72.0*w/self.image_dpi
+        else:
+            w = dx
+
+        if dy is None:
+            h = 72.0*h/self.image_dpi
+        else:
+            h = dy
+
         oid = getattr(im, '_gid', None)
         url = getattr(im, '_url', None)
         if url is not None:
@@ -1113,25 +1130,17 @@ class FigureCanvasSVG(FigureCanvasBase):
 
     def _print_svg(self, filename, svgwriter, fh_to_close=None, **kwargs):
         try:
+            image_dpi = kwargs.pop("dpi", 72)
             self.figure.set_dpi(72.0)
             width, height = self.figure.get_size_inches()
             w, h = width*72, height*72
 
             if rcParams['svg.image_noscale']:
-                renderer = RendererSVG(w, h, svgwriter, filename)
+                renderer = RendererSVG(w, h, image_dpi, svgwriter, filename)
             else:
-                # setting mixed renderer dpi other than 72 results in
-                # incorrect size of the rasterized image. It seems that the
-                # svg internally uses fixed dpi of 72 and seems to cause
-                # the problem. I hope someone who knows the svg backends
-                # take a look at this problem. Meanwhile, the dpi
-                # parameter is ignored and image_dpi is fixed at 72. - JJL
-
-                #image_dpi = kwargs.pop("dpi", 72)
-                image_dpi = 72
                 _bbox_inches_restore = kwargs.pop("bbox_inches_restore", None)
                 renderer = MixedModeRenderer(self.figure,
-                    width, height, image_dpi, RendererSVG(w, h, svgwriter, filename),
+                    width, height, image_dpi, RendererSVG(w, h, image_dpi, svgwriter, filename),
                     bbox_inches_restore=_bbox_inches_restore)
 
             self.figure.draw(renderer)
diff --git a/lib/matplotlib/tests/test_image.py b/lib/matplotlib/tests/test_image.py
index 4556013..d11a0c9 100644
--- a/lib/matplotlib/tests/test_image.py
+++ b/lib/matplotlib/tests/test_image.py
@@ -160,6 +160,33 @@ def test_no_interpolation_origin():
     ax = fig.add_subplot(212)
     ax.imshow(np.arange(100).reshape((2, 50)), interpolation='none')
 
+
+@image_comparison(baseline_images=['rasterize_10dpi'], extensions=['pdf','svg'], tol=1.5e-3, remove_text=True)
+def test_rasterize_dpi():
+    # This test should check rasterized rendering with high output resolution.
+    # It plots a rasterized line and a normal image with implot. So it will catch
+    # when images end up in the wrong place in case of non-standard dpi setting.
+    # Instead of high-res rasterization i use low-res.  Therefor the fact that the 
+    # resolution is non-standard is is easily checked by image_comparison.
+    import numpy as np
+    import matplotlib.pyplot as plt
+    
+    img = np.asarray([[1, 2], [3, 4]])
+
+    fig, axes = plt.subplots(1, 3, figsize = (3, 1))
+    
+    axes[0].imshow(img)
+    
+    axes[1].plot([0,1],[0,1], linewidth=20., rasterized=True)
+    axes[1].set(xlim = (0,1), ylim = (-1, 2))
+    
+    axes[2].plot([0,1],[0,1], linewidth=20.)
+    axes[2].set(xlim = (0,1), ylim = (-1, 2))
+    
+    rcParams['savefig.dpi'] = 10
+
+
+
 if __name__=='__main__':
     import nose
     nose.runmodule(argv=['-s','--with-doctest'], exit=False)
-- 
1.7.4.1

