Revision: 8099
          http://matplotlib.svn.sourceforge.net/matplotlib/?rev=8099&view=rev
Author:   leejjoon
Date:     2010-01-28 20:37:46 +0000 (Thu, 28 Jan 2010)

Log Message:
-----------
experimental support of Image._image_skew_coordinate

Modified Paths:
--------------
    trunk/matplotlib/lib/matplotlib/image.py

Added Paths:
-----------
    trunk/matplotlib/examples/api/demo_affine_image.py

Added: trunk/matplotlib/examples/api/demo_affine_image.py
===================================================================
--- trunk/matplotlib/examples/api/demo_affine_image.py                          
(rev 0)
+++ trunk/matplotlib/examples/api/demo_affine_image.py  2010-01-28 20:37:46 UTC 
(rev 8099)
@@ -0,0 +1,51 @@
+#!/usr/bin/env python
+
+
+"""
+For the backends that supports draw_image with optional affine
+transform (e.g., ps backend), the image of the output should
+have its boundary matches the red rectangles.
+"""
+
+import numpy as np
+import matplotlib.cm as cm
+import matplotlib.mlab as mlab
+import matplotlib.pyplot as plt
+import matplotlib.transforms as mtransforms
+
+def get_image():
+    delta = 0.25
+    x = y = np.arange(-3.0, 3.0, delta)
+    X, Y = np.meshgrid(x, y)
+    Z1 = mlab.bivariate_normal(X, Y, 1.0, 1.0, 0.0, 0.0)
+    Z2 = mlab.bivariate_normal(X, Y, 1.5, 0.5, 1, 1)
+    Z = Z2-Z1  # difference of Gaussians
+    return Z
+
+def imshow_affine(ax, z, *kl, **kwargs):
+    im = ax.imshow(z, *kl, **kwargs)
+    x1, x2, y1, y2 = im.get_extent()
+    im._image_skew_coordinate = (x2, y1)
+    return im
+
+
+if 1:
+    ax = plt.subplot(111)
+    Z = get_image()
+    im = imshow_affine(ax, Z, interpolation='nearest', cmap=cm.jet,
+                       origin='lower', extent=[-2, 4, -3, 2])
+
+    trans_data2 = mtransforms.Affine2D().rotate_deg(30) + ax.transData
+    im.set_transform(trans_data2)
+
+    # display intended extent of the image
+    x1, x2, y1, y2 = im.get_extent()
+    x3, y3 = x2, y1
+
+    ax.plot([x1, x2, x2, x1, x1], [y1, y1, y2, y2, y1], "r--", lw=3,
+            transform=trans_data2)
+
+    ax.set_xlim(-3, 5)
+    ax.set_ylim(-4, 4)
+
+    plt.savefig("demo_affine_image")

Modified: trunk/matplotlib/lib/matplotlib/image.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/image.py    2010-01-28 19:09:20 UTC (rev 
8098)
+++ trunk/matplotlib/lib/matplotlib/image.py    2010-01-28 20:37:46 UTC (rev 
8099)
@@ -25,6 +25,7 @@
 from matplotlib._image import *
 
 from matplotlib.transforms import BboxBase
+import matplotlib.transforms as mtransforms
 
 class _AxesImageBase(martist.Artist, cm.ScalarMappable):
     zorder = 0
@@ -96,6 +97,12 @@
 
         self._imcache = None
 
+        # this is an expetimental attribute, if True, unsampled image
+        # will be drawn using the affine transform that are
+        # appropriately skewed so that the given postition
+        # corresponds to the actual position in the coordinate. -JJL
+        self._image_skew_coordinate = None
+
         self.update(kwargs)
 
     def get_size(self):
@@ -204,6 +211,36 @@
         return im, xmin, ymin, dxintv, dyintv, sx, sy
 
 
+    @staticmethod
+    def _get_rotate_and_skew_transform(x1, y1, x2, y2, x3, y3):
+        """
+        Retuen a transform that does
+         (x1, y1) -> (x1, y1)
+         (x2, y2) -> (x2, y2)
+         (x2, y1) -> (x3, y3)
+
+        It was intended to derive a skew transform that preserve the
+        lower-left corner (x1, y1) and top-right corner(x2,y2), but
+        change the the lower-right-corner(x2, y1) to a new position
+        (x3, y3).
+        """
+        tr1 = mtransforms.Affine2D()
+        tr1.translate(-x1, -y1)
+        x2a, y2a = tr1.transform_point((x2, y2))
+        x3a, y3a = tr1.transform_point((x3, y3))
+
+        inv_mat = 1./(x2a*y3a-y2a*x3a) * np.mat([[y3a, -y2a],[-x3a, x2a]])
+
+        a, b = (inv_mat * np.mat([[x2a], [x2a]])).flat
+        c, d = (inv_mat * np.mat([[y2a], [0]])).flat
+
+        tr2 = mtransforms.Affine2D.from_values(a, c, b, d, 0, 0)
+
+        tr = (tr1 + tr2 + mtransforms.Affine2D().translate(x1, 
y1)).inverted().get_affine()
+
+        return tr
+
+
     def _draw_unsampled_image(self, renderer, gc):
         """
         draw unsampled image. The renderer should support a draw_image method
@@ -227,13 +264,25 @@
         im._url = self.get_url()
 
         trans = self.get_transform() #axes.transData
-        xx1, yy1 = trans.transform_non_affine((xmin, ymin))
-        xx2, yy2 = trans.transform_non_affine((xmin+dxintv, ymin+dyintv))
+        xy = trans.transform_non_affine([(xmin, ymin),
+                                         (xmin+dxintv, ymin+dyintv)])
+        xx1, yy1 = xy[0]
+        xx2, yy2 = xy[1]
 
-        renderer.draw_image(gc, xx1, yy1, im, xx2-xx1, yy2-yy1,
-                            trans.get_affine())
+        if self._image_skew_coordinate:
+            # skew the image when required.
+            x_lrc, y_lrc = self._image_skew_coordinate
+            xy = trans.transform_non_affine([(x_lrc, y_lrc)])
+            xx3, yy3 = xy[0]
 
+            tr_rotate_skew = self._get_rotate_and_skew_transform(xx1, yy1, 
xx2, yy2, xx3, yy3)
+            tr = tr_rotate_skew+trans.get_affine()
+        else:
+            tr = trans.get_affine()
 
+        renderer.draw_image(gc, xx1, yy1, im, xx2-xx1, yy2-yy1, tr)
+
+
     def _check_unsampled_image(self, renderer):
         """
         return True if the image is better to be drawn unsampled.


This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.

------------------------------------------------------------------------------
The Planet: dedicated and managed hosting, cloud storage, colocation
Stay online with enterprise data centers and the best network in the business
Choose flexible plans and management services without long-term contracts
Personal 24x7 support from experience hosting pros just a phone call away.
http://p.sf.net/sfu/theplanet-com
_______________________________________________
Matplotlib-checkins mailing list
Matplotlib-checkins@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/matplotlib-checkins

Reply via email to