Revision: 7423
http://matplotlib.svn.sourceforge.net/matplotlib/?rev=7423&view=rev
Author: leejjoon
Date: 2009-08-08 02:06:56 +0000 (Sat, 08 Aug 2009)
Log Message:
-----------
BboxImage implemented and two examples added.
Modified Paths:
--------------
trunk/matplotlib/CHANGELOG
trunk/matplotlib/lib/matplotlib/image.py
Added Paths:
-----------
trunk/matplotlib/examples/pylab_examples/demo_bboximage.py
trunk/matplotlib/examples/pylab_examples/demo_ribbon_box.py
Modified: trunk/matplotlib/CHANGELOG
===================================================================
--- trunk/matplotlib/CHANGELOG 2009-08-08 01:46:44 UTC (rev 7422)
+++ trunk/matplotlib/CHANGELOG 2009-08-08 02:06:56 UTC (rev 7423)
@@ -1,3 +1,6 @@
+2009-08-07 BboxImage implemented. Two examples, demo_bboximage.py and
+ demo_ribbon_box.py added. - JJL
+
2009-08-07 In an effort to simplify the backend API, all clipping rectangles
and paths are now passed in using GraphicsContext objects, even
on collections and images. Therefore:
Added: trunk/matplotlib/examples/pylab_examples/demo_bboximage.py
===================================================================
--- trunk/matplotlib/examples/pylab_examples/demo_bboximage.py
(rev 0)
+++ trunk/matplotlib/examples/pylab_examples/demo_bboximage.py 2009-08-08
02:06:56 UTC (rev 7423)
@@ -0,0 +1,62 @@
+import matplotlib.pyplot as plt
+import numpy as np
+from matplotlib.image import BboxImage
+from matplotlib.transforms import Bbox, TransformedBbox
+
+if __name__ == "__main__":
+
+ fig = plt.figure(1)
+ ax = plt.subplot(121)
+
+ txt = ax.text(0.5, 0.5, "test", size=30, ha="center", color="w")
+ kwargs = dict()
+
+ bbox_image = BboxImage(txt.get_window_extent,
+ norm = None,
+ origin=None,
+ clip_on=False,
+ **kwargs
+ )
+ a = np.arange(256).reshape(1,256)/256.
+ bbox_image.set_data(a)
+ ax.add_artist(bbox_image)
+
+
+ ax = plt.subplot(122)
+ a = np.linspace(0, 1, 256).reshape(1,-1)
+ a = np.vstack((a,a))
+
+ maps = sorted(m for m in plt.cm.datad if not m.endswith("_r"))
+ #nmaps = len(maps) + 1
+
+ #fig.subplots_adjust(top=0.99, bottom=0.01, left=0.2, right=0.99)
+
+ ncol = 2
+ nrow = len(maps)//ncol + 1
+
+ xpad_fraction = 0.3
+ dx = 1./(ncol + xpad_fraction*(ncol-1))
+
+ ypad_fraction = 0.3
+ dy = 1./(nrow + ypad_fraction*(nrow-1))
+
+ for i,m in enumerate(maps):
+ ix, iy = divmod(i, nrow)
+ #plt.figimage(a, 10, i*10, cmap=plt.get_cmap(m), origin='lower')
+ bbox0 = Bbox.from_bounds(ix*dx*(1+xpad_fraction),
+ 1.-iy*dy*(1+ypad_fraction)-dy,
+ dx, dy)
+ bbox = TransformedBbox(bbox0, ax.transAxes)
+
+ bbox_image = BboxImage(bbox,
+ cmap = plt.get_cmap(m),
+ norm = None,
+ origin=None,
+ **kwargs
+ )
+
+ bbox_image.set_data(a)
+ ax.add_artist(bbox_image)
+
+ plt.draw()
+ plt.show()
Added: trunk/matplotlib/examples/pylab_examples/demo_ribbon_box.py
===================================================================
--- trunk/matplotlib/examples/pylab_examples/demo_ribbon_box.py
(rev 0)
+++ trunk/matplotlib/examples/pylab_examples/demo_ribbon_box.py 2009-08-08
02:06:56 UTC (rev 7423)
@@ -0,0 +1,140 @@
+import matplotlib.pyplot as plt
+import numpy as np
+from matplotlib.image import BboxImage
+
+from matplotlib._png import read_png
+import matplotlib.colors
+from matplotlib.cbook import get_sample_data
+
+class RibbonBox(object):
+
+ original_image = read_png(get_sample_data("Minduka_Present_Blue_Pack.png",
+ asfileobj=False))
+ cut_location = 70
+ b_and_h = original_image[:,:,2]
+ color = original_image[:,:,2] - original_image[:,:,0]
+ alpha = original_image[:,:,3]
+ nx = original_image.shape[1]
+
+ def __init__(self, color):
+ rgb = matplotlib.colors.colorConverter.to_rgb(color)
+
+ im = np.empty(self.original_image.shape,
+ self.original_image.dtype)
+
+
+ im[:,:,:3] = self.b_and_h[:,:,np.newaxis]
+ im[:,:,:3] -= self.color[:,:,np.newaxis]*(1.-np.array(rgb))
+ im[:,:,3] = self.alpha
+
+ self.im = im
+
+
+ def get_stretched_image(self, stretch_factor):
+ stretch_factor = max(stretch_factor, 1)
+ ny, nx, nch = self.im.shape
+ ny2 = int(ny*stretch_factor)
+
+ stretched_image = np.empty((ny2, nx, nch),
+ self.im.dtype)
+ cut = self.im[self.cut_location,:,:]
+ stretched_image[:,:,:] = cut
+ stretched_image[:self.cut_location,:,:] = \
+ self.im[:self.cut_location,:,:]
+ stretched_image[-(ny-self.cut_location):,:,:] = \
+ self.im[-(ny-self.cut_location):,:,:]
+
+ self._cached_im = stretched_image
+ return stretched_image
+
+
+
+class RibbonBoxImage(BboxImage):
+ zorder = 1
+
+ def __init__(self, bbox, color,
+ cmap = None,
+ norm = None,
+ interpolation=None,
+ origin=None,
+ filternorm=1,
+ filterrad=4.0,
+ resample = False,
+ **kwargs
+ ):
+
+ BboxImage.__init__(self, bbox,
+ cmap = None,
+ norm = None,
+ interpolation=None,
+ origin=None,
+ filternorm=1,
+ filterrad=4.0,
+ resample = False,
+ **kwargs
+ )
+
+ self._ribbonbox = RibbonBox(color)
+ self._cached_ny = None
+
+
+ def draw(self, renderer, *args, **kwargs):
+
+ bbox = self.get_window_extent(renderer)
+ stretch_factor = bbox.height / bbox.width
+
+ ny = int(stretch_factor*self._ribbonbox.nx)
+ if self._cached_ny != ny:
+ arr = self._ribbonbox.get_stretched_image(stretch_factor)
+ self.set_array(arr)
+ self._cached_ny = ny
+
+ BboxImage.draw(self, renderer, *args, **kwargs)
+
+
+if 1:
+ from matplotlib.transforms import Bbox, TransformedBbox
+ from matplotlib.ticker import ScalarFormatter
+
+ fig = plt.gcf()
+ fig.clf()
+ ax = plt.subplot(111)
+
+ years = np.arange(2004, 2009)
+ box_colors = [(0.8, 0.2, 0.2),
+ (0.2, 0.8, 0.2),
+ (0.2, 0.2, 0.8),
+ (0.7, 0.5, 0.8),
+ (0.3, 0.8, 0.7),
+ ]
+ heights = np.random.random(years.shape) * 7000 + 3000
+
+ fmt = ScalarFormatter(useOffset=False)
+ ax.xaxis.set_major_formatter(fmt)
+
+ for year, h, bc in zip(years, heights, box_colors):
+ bbox0 = Bbox.from_extents(year-0.4, 0., year+0.4, h)
+ bbox = TransformedBbox(bbox0, ax.transData)
+ rb_patch = RibbonBoxImage(bbox, bc)
+
+ ax.add_artist(rb_patch)
+
+ ax.annotate(r"%d" % (int(h/100.)*100),
+ (year, h), va="bottom", ha="center")
+
+ patch_gradient = BboxImage(ax.bbox,
+ interpolation="bicubic",
+ zorder=0.1,
+ )
+ gradient = np.zeros((2, 2, 4), dtype=np.float)
+ gradient[:,:,:3] = [1, 1, 0.]
+ gradient[:,:,3] = [[0.1, 0.3],[0.3, 0.5]] # alpha channel
+ patch_gradient.set_array(gradient)
+ ax.add_artist(patch_gradient)
+
+
+ ax.set_xlim(years[0]-0.5, years[-1]+0.5)
+ ax.set_ylim(0, 10000)
+
+ plt.show()
+
Modified: trunk/matplotlib/lib/matplotlib/image.py
===================================================================
--- trunk/matplotlib/lib/matplotlib/image.py 2009-08-08 01:46:44 UTC (rev
7422)
+++ trunk/matplotlib/lib/matplotlib/image.py 2009-08-08 02:06:56 UTC (rev
7423)
@@ -24,6 +24,8 @@
# the image namespace:
from matplotlib._image import *
+from matplotlib.transforms import BboxBase
+
class AxesImage(martist.Artist, cm.ScalarMappable):
zorder = 1
# map interpolation strings to module constants
@@ -744,6 +746,149 @@
rows, cols, buffer = im.as_rgba_str()
_png.write_png(buffer, cols, rows, fname)
+
+class BboxImage(AxesImage):
+ """
+ The Image class whose size is determined by the given bbox.
+ """
+ zorder = 1
+ def __init__(self, bbox,
+ cmap = None,
+ norm = None,
+ interpolation=None,
+ origin=None,
+ filternorm=1,
+ filterrad=4.0,
+ resample = False,
+ **kwargs
+ ):
+
+ """
+ cmap is a colors.Colormap instance
+ norm is a colors.Normalize instance to map luminance to 0-1
+
+ kwargs are an optional list of Artist keyword args
+ """
+
+ AxesImage.__init__(self, ax=None,
+ cmap = cmap,
+ norm = norm,
+ interpolation=interpolation,
+ origin=origin,
+ filternorm=filternorm,
+ filterrad=filterrad,
+ resample = resample,
+ **kwargs
+ )
+
+ self.bbox = bbox
+
+ def get_window_extent(self, renderer=None):
+ if renderer is None:
+ renderer = self.get_figure()._cachedRenderer
+
+ if isinstance(self.bbox, BboxBase):
+ return self.bbox
+ elif callable(self.bbox):
+ return self.bbox(renderer)
+ else:
+ raise ValueError("unknown type of bbox")
+
+
+ def contains(self, mouseevent):
+ """Test whether the mouse event occured within the image.
+ """
+
+ if callable(self._contains): return self._contains(self,mouseevent)
+
+ if not self.get_visible():# or self.get_figure()._renderer is None:
+ return False,{}
+
+ x, y = mouseevent.x, mouseevent.y
+ inside = self.get_window_extent().contains(x, y)
+
+ return inside,{}
+
+ def get_size(self):
+ 'Get the numrows, numcols of the input image'
+ if self._A is None:
+ raise RuntimeError('You must first set the image array')
+
+ return self._A.shape[:2]
+
+ def make_image(self, renderer, magnification=1.0):
+ if self._A is None:
+ raise RuntimeError('You must first set the image array or the
image attribute')
+
+ if self._imcache is None:
+ if self._A.dtype == np.uint8 and len(self._A.shape) == 3:
+ im = _image.frombyte(self._A, 0)
+ im.is_grayscale = False
+ else:
+ if self._rgbacache is None:
+ x = self.to_rgba(self._A, self._alpha)
+ self._rgbacache = x
+ else:
+ x = self._rgbacache
+ im = _image.fromarray(x, 0)
+ if len(self._A.shape) == 2:
+ im.is_grayscale = self.cmap.is_gray()
+ else:
+ im.is_grayscale = False
+ self._imcache = im
+
+ if self.origin=='upper':
+ im.flipud_in()
+ else:
+ im = self._imcache
+
+ if 0:
+ fc = self.axes.patch.get_facecolor()
+ bg = mcolors.colorConverter.to_rgba(fc, 0)
+ im.set_bg( *bg)
+
+ # image input dimensions
+ im.reset_matrix()
+
+ im.set_interpolation(self._interpd[self._interpolation])
+
+ im.set_resample(self._resample)
+
+ l, b, r, t = self.get_window_extent(renderer).extents #bbox.extents
+ widthDisplay = (round(r) + 0.5) - (round(l) - 0.5)
+ heightDisplay = (round(t) + 0.5) - (round(b) - 0.5)
+ widthDisplay *= magnification
+ heightDisplay *= magnification
+ #im.apply_translation(tx, ty)
+
+ numrows, numcols = self._A.shape[:2]
+
+ # resize viewport to display
+ rx = widthDisplay / numcols
+ ry = heightDisplay / numrows
+ #im.apply_scaling(rx*sx, ry*sy)
+ im.apply_scaling(rx, ry)
+ #im.resize(int(widthDisplay+0.5), int(heightDisplay+0.5),
+ # norm=self._filternorm, radius=self._filterrad)
+ im.resize(int(widthDisplay), int(heightDisplay),
+ norm=self._filternorm, radius=self._filterrad)
+ return im
+
+
+ @allow_rasterization
+ def draw(self, renderer, *args, **kwargs):
+ if not self.get_visible(): return
+ # todo: we should be able to do some cacheing here
+ image_mag = renderer.get_image_magnification()
+ im = self.make_image(renderer, image_mag)
+ l, b, r, t = self.get_window_extent(renderer).extents
+ gc = renderer.new_gc()
+ self._set_gc_clip(gc)
+ #gc.set_clip_path(self.get_clip_path())
+ renderer.draw_image(gc, round(l), round(b), im)
+
+
+
def imread(fname):
"""
Return image file in *fname* as :class:`numpy.array`.
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
------------------------------------------------------------------------------
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day
trial. Simplify your report design, integration and deployment - and focus on
what you do best, core application coding. Discover what's new with
Crystal Reports now. http://p.sf.net/sfu/bobj-july
_______________________________________________
Matplotlib-checkins mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/matplotlib-checkins