## matplotlib-users

 [Matplotlib-users] Path object where different vertices use different transforms? From: Uri Laserson - 2009-09-28 14:04:42 ```Is it possible to specify a path object that will use different transforms for different vertices? This is again related to plotting a box whose height is specified by data coords, but whose width is a constant in axes coords regardless of scale (so linear and log x-scales would produce a box of the same width). Ideally, I would draw a path like this: 1. the center of the box would be located at x and bottom and top would be y1, y2, all in data coords 2. I would move to (x,y1) at the bottom-center of the box. 3. The x value would now need to be converted to Axes coords, possibly by applying transData + transAxes.inverted 4. I would want to draw a line to (x-0.1, y1) where x is now in axes coords and y is still in data coords. Then up, then right, then down, and then close the polygon. How do I implement this? As I mentioned before, a blended transform would allow me to make the moves i am interested in. However, a change of scale would change the correspondence between data and axes coords, so the axes transform part of the blended axes would have to be recomputed everytime the scale changes based on where the (x,y1) point lands in the axes. Is this correct? Any suggestions are welcome...thanks! Uri -- Uri Laserson PhD Candidate, Biomedical Engineering Harvard Medical School (Genetics) Massachusetts Institute of Technology (Mathematics) phone +1 917 742 8019 laserson@... ```
 Re: [Matplotlib-users] Path object where different vertices use different transforms? From: Michael Droettboom - 2009-09-28 18:04:20 ```I don't think the transformations framework is going to be of much help for automating this. You seem to be suggesting an x-axis where the center is in data coords and the width is in axes coords. Once you've added the two together, it will be impossible to separate them. I think the path of least resistance will be for you to create a new artist class and override the draw method, such that you can do all the necessary calculations based on the current values of the axes and data transforms on every draw. There's an example of creating a custom artist in api/line_with_text.py... Then it's just writing a draw method to do what you need to do -- you should be able to get at the axes transformations through self.axes.transAxes and self.axes.transData. I'm a bit busy today to really work that through, but hopefully that's enough to get you started. Mike Uri Laserson wrote: > Is it possible to specify a path object that will use different > transforms for different vertices? > > This is again related to plotting a box whose height is specified by > data coords, but whose width is a constant in axes coords regardless > of scale (so linear and log x-scales would produce a box of the same > width). > > Ideally, I would draw a path like this: > 1. the center of the box would be located at x and bottom and top > would be y1, y2, all in data coords > 2. I would move to (x,y1) at the bottom-center of the box. > 3. The x value would now need to be converted to Axes coords, possibly > by applying transData + transAxes.inverted > 4. I would want to draw a line to (x-0.1, y1) where x is now in axes > coords and y is still in data coords. Then up, then right, then down, > and then close the polygon. > > How do I implement this? > > As I mentioned before, a blended transform would allow me to make the > moves i am interested in. However, a change of scale would change the > correspondence between data and axes coords, so the axes transform > part of the blended axes would have to be recomputed everytime the > scale changes based on where the (x,y1) point lands in the axes. Is > this correct? > > Any suggestions are welcome...thanks! > > Uri > > > -- Michael Droettboom Science Software Branch Operations and Engineering Division Space Telescope Science Institute Operated by AURA for NASA ```
 Re: [Matplotlib-users] Path object where different vertices use different transforms? From: Eric Firing - 2009-09-28 19:04:53 ```Uri Laserson wrote: > Is it possible to specify a path object that will use different > transforms for different vertices? > > This is again related to plotting a box whose height is specified by > data coords, but whose width is a constant in axes coords regardless > of scale (so linear and log x-scales would produce a box of the same > width). > > Ideally, I would draw a path like this: > 1. the center of the box would be located at x and bottom and top > would be y1, y2, all in data coords > 2. I would move to (x,y1) at the bottom-center of the box. > 3. The x value would now need to be converted to Axes coords, possibly > by applying transData + transAxes.inverted > 4. I would want to draw a line to (x-0.1, y1) where x is now in axes > coords and y is still in data coords. Then up, then right, then down, > and then close the polygon. > > How do I implement this? I must be missing something, because I still don't see why you can't do all this very simply by using a PolyCollection, with the vertices in axes coordinates and the offset in data coordinates. Eric > > As I mentioned before, a blended transform would allow me to make the > moves i am interested in. However, a change of scale would change the > correspondence between data and axes coords, so the axes transform > part of the blended axes would have to be recomputed everytime the > scale changes based on where the (x,y1) point lands in the axes. Is > this correct? > > Any suggestions are welcome...thanks! > > Uri > > ```
 Re: [Matplotlib-users] Path object where different vertices use different transforms? From: Michael Droettboom - 2009-09-28 20:04:04 ```If I understand correctly, the top and bottom of the box are in data coordinates, the x-center of the box is in data coordinates, only the width of the box is in axes coordinates. Is that correct? If so, a PolyCollection won't be able to do this (directly), since that would require both the width and height to be in axes coordinates. Mike Eric Firing wrote: > Uri Laserson wrote: > >> Is it possible to specify a path object that will use different >> transforms for different vertices? >> >> This is again related to plotting a box whose height is specified by >> data coords, but whose width is a constant in axes coords regardless >> of scale (so linear and log x-scales would produce a box of the same >> width). >> >> Ideally, I would draw a path like this: >> 1. the center of the box would be located at x and bottom and top >> would be y1, y2, all in data coords >> 2. I would move to (x,y1) at the bottom-center of the box. >> 3. The x value would now need to be converted to Axes coords, possibly >> by applying transData + transAxes.inverted >> 4. I would want to draw a line to (x-0.1, y1) where x is now in axes >> coords and y is still in data coords. Then up, then right, then down, >> and then close the polygon. >> >> How do I implement this? >> > > I must be missing something, because I still don't see why you can't do > all this very simply by using a PolyCollection, with the vertices in > axes coordinates and the offset in data coordinates. > > Eric > > >> As I mentioned before, a blended transform would allow me to make the >> moves i am interested in. However, a change of scale would change the >> correspondence between data and axes coords, so the axes transform >> part of the blended axes would have to be recomputed everytime the >> scale changes based on where the (x,y1) point lands in the axes. Is >> this correct? >> >> Any suggestions are welcome...thanks! >> >> Uri >> >> >> > > > ------------------------------------------------------------------------------ > Come build with us! The BlackBerry® Developer Conference in SF, CA > is the only developer event you need to attend this year. Jumpstart your > developing skills, take BlackBerry mobile applications to market and stay > ahead of the curve. Join us from November 9-12, 2009. Register now! > http://p.sf.net/sfu/devconf > _______________________________________________ > Matplotlib-users mailing list > Matplotlib-users@... > https://lists.sourceforge.net/lists/listinfo/matplotlib-users > -- Michael Droettboom Science Software Branch Operations and Engineering Division Space Telescope Science Institute Operated by AURA for NASA ```
 Re: [Matplotlib-users] Path object where different vertices use different transforms? From: Uri Laserson - 2009-09-28 20:15:46 ```On Mon, Sep 28, 2009 at 16:03, Michael Droettboom wrote: > If I understand correctly, the top and bottom of the box are in data > coordinates, the x-center of the box is in data coordinates, only the width > of the box is in axes coordinates.  Is that correct?  If so, a That's exactly correct. > PolyCollection won't be able to do this (directly), since that would require > both the width and height to be in axes coordinates. In principle, could you use a blended tranform for that? Eitherway, I don't think it would work, because the patch objects would be drawn to specific Axes coords. If the scale is changed (e.g, by switching to log scale), then what would prompt the Axes coords to be recalculated? I was thinking earlier that I could compose the transData and transAxes.inverse transforms to recalculate where the new Axes coord should be, but Mike thought this approach would fail (though I'm still not exactly sure why, no doubt because of my own ignorance). Uri > > Mike > > Eric Firing wrote: >> >> Uri Laserson wrote: >> >>> >>> Is it possible to specify a path object that will use different >>> transforms for different vertices? >>> >>> This is again related to plotting a box whose height is specified by >>> data coords, but whose width is a constant in axes coords regardless >>> of scale (so linear and log x-scales would produce a box of the same >>> width). >>> >>> Ideally, I would draw a path like this: >>> 1. the center of the box would be located at x and bottom and top >>> would be y1, y2, all in data coords >>> 2. I would move to (x,y1) at the bottom-center of the box. >>> 3. The x value would now need to be converted to Axes coords, possibly >>> by applying transData + transAxes.inverted >>> 4. I would want to draw a line to (x-0.1, y1) where x is now in axes >>> coords and y is still in data coords.  Then up, then right, then down, >>> and then close the polygon. >>> >>> How do I implement this? >>> >> >> I must be missing something, because I still don't see why you can't do >> all this very simply by using a PolyCollection, with the vertices in axes >> coordinates and the offset in data coordinates. >> >> Eric >> >> >>> >>> As I mentioned before, a blended transform would allow me to make the >>> moves i am interested in.  However, a change of scale would change the >>> correspondence between data and axes coords, so the axes transform >>> part of the blended axes would have to be recomputed everytime the >>> scale changes based on where the (x,y1) point lands in the axes.  Is >>> this correct? >>> >>> Any suggestions are welcome...thanks! >>> >>> Uri >>> >>> >>> >> >> >> >> ------------------------------------------------------------------------------ >> Come build with us! The BlackBerry® Developer Conference in SF, CA >> is the only developer event you need to attend this year. Jumpstart your >> developing skills, take BlackBerry mobile applications to market and stay >> ahead of the curve. Join us from November 9-12, 2009. Register now! >> http://p.sf.net/sfu/devconf >> _______________________________________________ >> Matplotlib-users mailing list >> Matplotlib-users@... >> https://lists.sourceforge.net/lists/listinfo/matplotlib-users >> > > -- > Michael Droettboom > Science Software Branch > Operations and Engineering Division > Space Telescope Science Institute > Operated by AURA for NASA > > -- Uri Laserson PhD Candidate, Biomedical Engineering Harvard Medical School (Genetics) Massachusetts Institute of Technology (Mathematics) phone +1 917 742 8019 laserson@... ```
 Re: [Matplotlib-users] Path object where different vertices use different transforms? From: Jae-Joon Lee - 2009-09-28 20:53:34 ```On Mon, Sep 28, 2009 at 4:15 PM, Uri Laserson wrote: > On Mon, Sep 28, 2009 at 16:03, Michael Droettboom wrote: >> If I understand correctly, the top and bottom of the box are in data >> coordinates, the x-center of the box is in data coordinates, only the width >> of the box is in axes coordinates.  Is that correct?  If so, a > > That's exactly correct. > I personally think that a box, whose height has a physical meaning (in data coordinate) while its width does not, is not a good representation of your data. A vertical line or something like errorbar seems to be more suitable to me. >> PolyCollection won't be able to do this (directly), since that would require >> both the width and height to be in axes coordinates. > > In principle, could you use a blended tranform for that?  Eitherway, I > don't think it would work, because the patch objects would be drawn to > specific Axes coords.  If the scale is changed (e.g, by switching to > log scale), then what would prompt the Axes coords to be recalculated? >  I was thinking earlier that I could compose the transData and > transAxes.inverse transforms to recalculate where the new Axes coord > should be, but Mike thought this approach would fail (though I'm still > not exactly sure why, no doubt because of my own ignorance). > As Mike has explained, the transform trick (blended or not) won't work. The width and y-center will be always transformed with the same transform, which is not what you want. I think you need to create a custom patch class for this to work. One option seems to subclass the Rectangle class and overide the _update_patch_transform method. The patch transform is used to transform a unit rectangle to a rectangle in data coordinate (or whatever coordinate the patch uses), i.e., you need to calculate the coordinate of the box in the data coordinate(or whatever coordinate the patch uses). -JJ > Uri > >> >> Mike >> >> Eric Firing wrote: >>> >>> Uri Laserson wrote: >>> >>>> >>>> Is it possible to specify a path object that will use different >>>> transforms for different vertices? >>>> >>>> This is again related to plotting a box whose height is specified by >>>> data coords, but whose width is a constant in axes coords regardless >>>> of scale (so linear and log x-scales would produce a box of the same >>>> width). >>>> >>>> Ideally, I would draw a path like this: >>>> 1. the center of the box would be located at x and bottom and top >>>> would be y1, y2, all in data coords >>>> 2. I would move to (x,y1) at the bottom-center of the box. >>>> 3. The x value would now need to be converted to Axes coords, possibly >>>> by applying transData + transAxes.inverted >>>> 4. I would want to draw a line to (x-0.1, y1) where x is now in axes >>>> coords and y is still in data coords.  Then up, then right, then down, >>>> and then close the polygon. >>>> >>>> How do I implement this? >>>> >>> >>> I must be missing something, because I still don't see why you can't do >>> all this very simply by using a PolyCollection, with the vertices in axes >>> coordinates and the offset in data coordinates. >>> >>> Eric >>> >>> >>>> >>>> As I mentioned before, a blended transform would allow me to make the >>>> moves i am interested in.  However, a change of scale would change the >>>> correspondence between data and axes coords, so the axes transform >>>> part of the blended axes would have to be recomputed everytime the >>>> scale changes based on where the (x,y1) point lands in the axes.  Is >>>> this correct? >>>> >>>> Any suggestions are welcome...thanks! >>>> >>>> Uri >>>> >>>> >>>> >>> >>> >>> >>> ------------------------------------------------------------------------------ >>> Come build with us! The BlackBerry® Developer Conference in SF, CA >>> is the only developer event you need to attend this year. Jumpstart your >>> developing skills, take BlackBerry mobile applications to market and stay >>> ahead of the curve. Join us from November 9-12, 2009. Register now! >>> http://p.sf.net/sfu/devconf >>> _______________________________________________ >>> Matplotlib-users mailing list >>> Matplotlib-users@... >>> https://lists.sourceforge.net/lists/listinfo/matplotlib-users >>> >> >> -- >> Michael Droettboom >> Science Software Branch >> Operations and Engineering Division >> Space Telescope Science Institute >> Operated by AURA for NASA >> >> > > > > -- > Uri Laserson > PhD Candidate, Biomedical Engineering > Harvard Medical School (Genetics) > Massachusetts Institute of Technology (Mathematics) > phone +1 917 742 8019 > laserson@... > > ------------------------------------------------------------------------------ > Come build with us! The BlackBerry® Developer Conference in SF, CA > is the only developer event you need to attend this year. Jumpstart your > developing skills, take BlackBerry mobile applications to market and stay > ahead of the curve. Join us from November 9-12, 2009. Register now! > http://p.sf.net/sfu/devconf > _______________________________________________ > Matplotlib-users mailing list > Matplotlib-users@... > https://lists.sourceforge.net/lists/listinfo/matplotlib-users > ```
 Re: [Matplotlib-users] Path object where different vertices use different transforms? From: Michael Droettboom - 2009-09-28 20:57:12 Attachments: custom_box.py ```Is the attached sort of what you want? It defines a custom rectangle by (x, w, y1, y2) and overrides the get_transform of the patch to update itself at draw time. Mike Uri Laserson wrote: > On Mon, Sep 28, 2009 at 16:03, Michael Droettboom wrote: > >> If I understand correctly, the top and bottom of the box are in data >> coordinates, the x-center of the box is in data coordinates, only the width >> of the box is in axes coordinates. Is that correct? If so, a >> > > That's exactly correct. > > >> PolyCollection won't be able to do this (directly), since that would require >> both the width and height to be in axes coordinates. >> > > In principle, could you use a blended tranform for that? Eitherway, I > don't think it would work, because the patch objects would be drawn to > specific Axes coords. If the scale is changed (e.g, by switching to > log scale), then what would prompt the Axes coords to be recalculated? > I was thinking earlier that I could compose the transData and > transAxes.inverse transforms to recalculate where the new Axes coord > should be, but Mike thought this approach would fail (though I'm still > not exactly sure why, no doubt because of my own ignorance). > > Uri > > >> Mike >> >> Eric Firing wrote: >> >>> Uri Laserson wrote: >>> >>> >>>> Is it possible to specify a path object that will use different >>>> transforms for different vertices? >>>> >>>> This is again related to plotting a box whose height is specified by >>>> data coords, but whose width is a constant in axes coords regardless >>>> of scale (so linear and log x-scales would produce a box of the same >>>> width). >>>> >>>> Ideally, I would draw a path like this: >>>> 1. the center of the box would be located at x and bottom and top >>>> would be y1, y2, all in data coords >>>> 2. I would move to (x,y1) at the bottom-center of the box. >>>> 3. The x value would now need to be converted to Axes coords, possibly >>>> by applying transData + transAxes.inverted >>>> 4. I would want to draw a line to (x-0.1, y1) where x is now in axes >>>> coords and y is still in data coords. Then up, then right, then down, >>>> and then close the polygon. >>>> >>>> How do I implement this? >>>> >>>> >>> I must be missing something, because I still don't see why you can't do >>> all this very simply by using a PolyCollection, with the vertices in axes >>> coordinates and the offset in data coordinates. >>> >>> Eric >>> >>> >>> >>>> As I mentioned before, a blended transform would allow me to make the >>>> moves i am interested in. However, a change of scale would change the >>>> correspondence between data and axes coords, so the axes transform >>>> part of the blended axes would have to be recomputed everytime the >>>> scale changes based on where the (x,y1) point lands in the axes. Is >>>> this correct? >>>> >>>> Any suggestions are welcome...thanks! >>>> >>>> Uri >>>> >>>> >>>> >>>> >>> >>> ------------------------------------------------------------------------------ >>> Come build with us! The BlackBerry® Developer Conference in SF, CA >>> is the only developer event you need to attend this year. Jumpstart your >>> developing skills, take BlackBerry mobile applications to market and stay >>> ahead of the curve. Join us from November 9-12, 2009. Register now! >>> http://p.sf.net/sfu/devconf >>> _______________________________________________ >>> Matplotlib-users mailing list >>> Matplotlib-users@... >>> https://lists.sourceforge.net/lists/listinfo/matplotlib-users >>> >>> >> -- >> Michael Droettboom >> Science Software Branch >> Operations and Engineering Division >> Space Telescope Science Institute >> Operated by AURA for NASA >> >> >> > > > > -- Michael Droettboom Science Software Branch Operations and Engineering Division Space Telescope Science Institute Operated by AURA for NASA ```
 Re: [Matplotlib-users] Path object where different vertices use different transforms? From: Uri Laserson - 2009-09-28 22:42:07 ```Hi Mike, This is definitely on the right track. Thanks a lot for writing it out. When I change the view limits, indeed the width stays constant while the height gets rescaled. However, when I try to change to a logarithmic axis, I get the following errors. Again, excuse my ignorance, but I am not sure where exactly the offense is and how to fix it. In [57]: ax.set_xscale('log') In [58]: plt.draw() ERROR: An unexpected error occurred while tokenizing input The following traceback may be corrupted or invalid The error message is: ('EOF in multi-line statement', (568, 0)) ERROR: An unexpected error occurred while tokenizing input The following traceback may be corrupted or invalid The error message is: ('EOF in multi-line statement', (568, 0)) ERROR: An unexpected error occurred while tokenizing input The following traceback may be corrupted or invalid The error message is: ('EOF in multi-line statement', (568, 0)) --------------------------------------------------------------------------- TypeError Traceback (most recent call last) /Users/laserson/Desktop/ in () /Library/Frameworks/Python.framework/Versions/4.3.0/lib/python2.5/site-packages/matplotlib/pyplot.pyc in draw() 348 def draw(): 349 'redraw the current figure' --> 350 get_current_fig_manager().canvas.draw() 351 352 @docstring.copy_dedent(Figure.savefig) /Library/Frameworks/Python.framework/Versions/4.3.0/lib/python2.5/site-packages/matplotlib/backends/backend_tkagg.pyc in draw(self) 213 214 def draw(self): --> 215 FigureCanvasAgg.draw(self) 216 tkagg.blit(self._tkphoto, self.renderer._renderer, colormode=2) 217 self._master.update_idletasks() /Library/Frameworks/Python.framework/Versions/4.3.0/lib/python2.5/site-packages/matplotlib/backends/backend_agg.pyc in draw(self) 376 377 self.renderer = self.get_renderer() --> 378 self.figure.draw(self.renderer) 379 380 def get_renderer(self): /Library/Frameworks/Python.framework/Versions/4.3.0/lib/python2.5/site-packages/matplotlib/artist.pyc in draw_wrapper(artist, renderer, *kl) 53 def draw_wrapper(artist, renderer, *kl): 54 before(artist, renderer) ---> 55 draw(artist, renderer, *kl) 56 after(artist, renderer) 57 /Library/Frameworks/Python.framework/Versions/4.3.0/lib/python2.5/site-packages/matplotlib/figure.pyc in draw(self, renderer) 770 771 # render the axes --> 772 for a in self.axes: a.draw(renderer) 773 774 # render the figure text /Library/Frameworks/Python.framework/Versions/4.3.0/lib/python2.5/site-packages/matplotlib/artist.pyc in draw_wrapper(artist, renderer, *kl) 53 def draw_wrapper(artist, renderer, *kl): 54 before(artist, renderer) ---> 55 draw(artist, renderer, *kl) 56 after(artist, renderer) 57 /Library/Frameworks/Python.framework/Versions/4.3.0/lib/python2.5/site-packages/matplotlib/axes.pyc in draw(self, renderer, inframe) 1743 1744 for zorder, i, a in dsu: -> 1745 a.draw(renderer) 1746 1747 renderer.close_group('axes') /Library/Frameworks/Python.framework/Versions/4.3.0/lib/python2.5/site-packages/matplotlib/artist.pyc in draw_wrapper(artist, renderer, *kl) 53 def draw_wrapper(artist, renderer, *kl): 54 before(artist, renderer) ---> 55 draw(artist, renderer, *kl) 56 after(artist, renderer) 57 /Library/Frameworks/Python.framework/Versions/4.3.0/lib/python2.5/site-packages/matplotlib/patches.pyc in draw(self, renderer) 353 354 path = self.get_path() --> 355 transform = self.get_transform() 356 tpath = transform.transform_path_non_affine(path) 357 affine = transform.get_affine() /Users/laserson/Desktop/testMyPatch.py in get_transform(self) 22 box = [[self.x, self.y1], 23 [self.x, self.y2]] ---> 24 box = self.axes.transData.transform(box) 25 26 # Get the width as a fraction of the axes width /Library/Frameworks/Python.framework/Versions/4.3.0/lib/python2.5/site-packages/matplotlib/transforms.pyc in transform(self, points) 1893 def transform(self, points): 1894 return self._b.transform( -> 1895 self._a.transform(points)) 1896 transform.__doc__ = Transform.transform.__doc__ 1897 /Library/Frameworks/Python.framework/Versions/4.3.0/lib/python2.5/site-packages/matplotlib/transforms.pyc in transform(self, points) 1721 x_points = x.transform(points)[:, 0:1] 1722 else: -> 1723 x_points = x.transform(points[:, 0]) 1724 x_points = x_points.reshape((len(x_points), 1)) 1725 TypeError: list indices must be integers On Mon, Sep 28, 2009 at 16:56, Michael Droettboom wrote: > Is the attached sort of what you want?  It defines a custom rectangle by (x, > w, y1, y2) and overrides the get_transform of the patch to update itself at > draw time. > > Mike > > Uri Laserson wrote: >> >> On Mon, Sep 28, 2009 at 16:03, Michael Droettboom wrote: >> >>> >>> If I understand correctly, the top and bottom of the box are in data >>> coordinates, the x-center of the box is in data coordinates, only the >>> width >>> of the box is in axes coordinates.  Is that correct?  If so, a >>> >> >> That's exactly correct. >> >> >>> >>> PolyCollection won't be able to do this (directly), since that would >>> require >>> both the width and height to be in axes coordinates. >>> >> >> In principle, could you use a blended tranform for that?  Eitherway, I >> don't think it would work, because the patch objects would be drawn to >> specific Axes coords.  If the scale is changed (e.g, by switching to >> log scale), then what would prompt the Axes coords to be recalculated? >>  I was thinking earlier that I could compose the transData and >> transAxes.inverse transforms to recalculate where the new Axes coord >> should be, but Mike thought this approach would fail (though I'm still >> not exactly sure why, no doubt because of my own ignorance). >> >> Uri >> >> >>> >>> Mike >>> >>> Eric Firing wrote: >>> >>>> >>>> Uri Laserson wrote: >>>> >>>> >>>>> >>>>> Is it possible to specify a path object that will use different >>>>> transforms for different vertices? >>>>> >>>>> This is again related to plotting a box whose height is specified by >>>>> data coords, but whose width is a constant in axes coords regardless >>>>> of scale (so linear and log x-scales would produce a box of the same >>>>> width). >>>>> >>>>> Ideally, I would draw a path like this: >>>>> 1. the center of the box would be located at x and bottom and top >>>>> would be y1, y2, all in data coords >>>>> 2. I would move to (x,y1) at the bottom-center of the box. >>>>> 3. The x value would now need to be converted to Axes coords, possibly >>>>> by applying transData + transAxes.inverted >>>>> 4. I would want to draw a line to (x-0.1, y1) where x is now in axes >>>>> coords and y is still in data coords.  Then up, then right, then down, >>>>> and then close the polygon. >>>>> >>>>> How do I implement this? >>>>> >>>>> >>>> >>>> I must be missing something, because I still don't see why you can't do >>>> all this very simply by using a PolyCollection, with the vertices in >>>> axes >>>> coordinates and the offset in data coordinates. >>>> >>>> Eric >>>> >>>> >>>> >>>>> >>>>> As I mentioned before, a blended transform would allow me to make the >>>>> moves i am interested in.  However, a change of scale would change the >>>>> correspondence between data and axes coords, so the axes transform >>>>> part of the blended axes would have to be recomputed everytime the >>>>> scale changes based on where the (x,y1) point lands in the axes.  Is >>>>> this correct? >>>>> >>>>> Any suggestions are welcome...thanks! >>>>> >>>>> Uri >>>>> >>>>> >>>>> >>>>> >>>> >>>> >>>> ------------------------------------------------------------------------------ >>>> Come build with us! The BlackBerry® Developer Conference in SF, CA >>>> is the only developer event you need to attend this year. Jumpstart your >>>> developing skills, take BlackBerry mobile applications to market and >>>> stay >>>> ahead of the curve. Join us from November 9-12, 2009. Register >>>> now! >>>> http://p.sf.net/sfu/devconf >>>> _______________________________________________ >>>> Matplotlib-users mailing list >>>> Matplotlib-users@... >>>> https://lists.sourceforge.net/lists/listinfo/matplotlib-users >>>> >>>> >>> >>> -- >>> Michael Droettboom >>> Science Software Branch >>> Operations and Engineering Division >>> Space Telescope Science Institute >>> Operated by AURA for NASA >>> >>> >>> >> >> >> >> > > -- > Michael Droettboom > Science Software Branch > Operations and Engineering Division > Space Telescope Science Institute > Operated by AURA for NASA > > > import numpy as np > import matplotlib.pyplot as plt > import matplotlib.patches as mpatches > import matplotlib.transforms as mtransforms > import matplotlib.path as mpath > > class MyBox(mpatches.Patch): > >   def __init__(self, x, w, y1, y2, **kwargs): >      self.x = x >      self.w = w >      self.y1 = y1 >      self.y2 = y2 >      mpatches.Patch.__init__(self, **kwargs) > >   def get_path(self): >      return mpath.Path.unit_rectangle() > >   def get_transform(self): > >      # Transform the data-relative values >      box = [[self.x, self.y1], >             [self.x, self.y2]] >      box = self.axes.transData.transform(box) > >      # Get the width as a fraction of the axes width >      w = self.w * self.axes.bbox.width / 2.0 > >      # Add it to the data-transformed coordinates >      box[0][0] -= w >      box[1][0] += w > >      return mtransforms.BboxTransformTo(mtransforms.Bbox(box)) > > fig = plt.figure() > ax = fig.add_subplot(111) > patch = MyBox(0, 0.1, 0.5, 1.5) > ax.add_patch(patch) > ax.set_xlim((-1, 1)) > ax.set_ylim((0, 2)) > > plt.show() > > -- Uri Laserson PhD Candidate, Biomedical Engineering Harvard Medical School (Genetics) Massachusetts Institute of Technology (Mathematics) phone +1 917 742 8019 laserson@... ```
 Re: [Matplotlib-users] Path object where different vertices use different transforms? From: Uri Laserson - 2009-09-28 23:00:23 ```On Mon, Sep 28, 2009 at 16:53, Jae-Joon Lee wrote: > I personally think that a box, whose height has a physical meaning (in > data coordinate) while its width does not, is not a good > representation of your data. A vertical line or something like > errorbar seems to be more suitable to me. I agree, and if you're a fan of Edward Tufte, then you definitely agree. In his book, he takes the simple Tukey-style boxplot and turns it into a 1-dimension object, in line with the type of data it's representing. However, I still want to implement something that's a bit more traditional, which is why I wanted to pick an arbitrary width for the boxes that stay invariant regardless of the scale that I use. > As Mike has explained, the transform trick (blended or not) won't > work. The width and y-center will be always transformed with the same > transform, which is not what you want. I think you need to create a > custom patch class for this to work. One option seems to subclass the > Rectangle class and overide the _update_patch_transform method. The > patch transform is used to transform a unit rectangle to a rectangle > in data coordinate (or whatever coordinate the patch uses), i.e., you > need to calculate the coordinate of the box in the data coordinate(or > whatever coordinate the patch uses). Could you possibly explain exactly what is going on and how this structurally differs from the approach that Mike posted? In Mike's code, he uses BboxTransformTo using the box he created in display coords. So this takes a unit square and spits out the box that I specify when I instantiate the custom patch (using data coords for x and y and axes coords for w). What is called to actually draw the box (i.e., when I execute plt.draw())? Is that get_path()? So basically, whenever MPL wants to draw a patch, does it always call get_path() and then runs it through whatever is returned from get_transform() to get the final shape in display coords? So how does this relate to the strategy that you are advocating? Is _update_patch_transform somehow a synonym for what I described in the paragraph above? I don't know where that fits into the picture. It may be useful to add something to the "Working With Tranformations" section or the "Transformation Tutorial" about what is minimally necessary to override for a custom patch. I have been playing around with MPL for some time now (albeit I don't have much computer visualization/graphics experience) and still have only a fuzzy idea of what order things are called in and what the overall strategy/structure of the system is like. Uri > > -JJ > >> Uri >> >>> >>> Mike >>> >>> Eric Firing wrote: >>>> >>>> Uri Laserson wrote: >>>> >>>>> >>>>> Is it possible to specify a path object that will use different >>>>> transforms for different vertices? >>>>> >>>>> This is again related to plotting a box whose height is specified by >>>>> data coords, but whose width is a constant in axes coords regardless >>>>> of scale (so linear and log x-scales would produce a box of the same >>>>> width). >>>>> >>>>> Ideally, I would draw a path like this: >>>>> 1. the center of the box would be located at x and bottom and top >>>>> would be y1, y2, all in data coords >>>>> 2. I would move to (x,y1) at the bottom-center of the box. >>>>> 3. The x value would now need to be converted to Axes coords, possibly >>>>> by applying transData + transAxes.inverted >>>>> 4. I would want to draw a line to (x-0.1, y1) where x is now in axes >>>>> coords and y is still in data coords.  Then up, then right, then down, >>>>> and then close the polygon. >>>>> >>>>> How do I implement this? >>>>> >>>> >>>> I must be missing something, because I still don't see why you can't do >>>> all this very simply by using a PolyCollection, with the vertices in axes >>>> coordinates and the offset in data coordinates. >>>> >>>> Eric >>>> >>>> >>>>> >>>>> As I mentioned before, a blended transform would allow me to make the >>>>> moves i am interested in.  However, a change of scale would change the >>>>> correspondence between data and axes coords, so the axes transform >>>>> part of the blended axes would have to be recomputed everytime the >>>>> scale changes based on where the (x,y1) point lands in the axes.  Is >>>>> this correct? >>>>> >>>>> Any suggestions are welcome...thanks! >>>>> >>>>> Uri >>>>> >>>>> >>>>> >>>> >>>> >>>> >>>> ------------------------------------------------------------------------------ >>>> Come build with us! The BlackBerry® Developer Conference in SF, CA >>>> is the only developer event you need to attend this year. Jumpstart your >>>> developing skills, take BlackBerry mobile applications to market and stay >>>> ahead of the curve. Join us from November 9-12, 2009. Register now! >>>> http://p.sf.net/sfu/devconf >>>> _______________________________________________ >>>> Matplotlib-users mailing list >>>> Matplotlib-users@... >>>> https://lists.sourceforge.net/lists/listinfo/matplotlib-users >>>> >>> >>> -- >>> Michael Droettboom >>> Science Software Branch >>> Operations and Engineering Division >>> Space Telescope Science Institute >>> Operated by AURA for NASA >>> >>> >> >> >> >> -- >> Uri Laserson >> PhD Candidate, Biomedical Engineering >> Harvard Medical School (Genetics) >> Massachusetts Institute of Technology (Mathematics) >> phone +1 917 742 8019 >> laserson@... >> >> ------------------------------------------------------------------------------ >> Come build with us! The BlackBerry® Developer Conference in SF, CA >> is the only developer event you need to attend this year. Jumpstart your >> developing skills, take BlackBerry mobile applications to market and stay >> ahead of the curve. Join us from November 9-12, 2009. Register now! >> http://p.sf.net/sfu/devconf >> _______________________________________________ >> Matplotlib-users mailing list >> Matplotlib-users@... >> https://lists.sourceforge.net/lists/listinfo/matplotlib-users >> > -- Uri Laserson PhD Candidate, Biomedical Engineering Harvard Medical School (Genetics) Massachusetts Institute of Technology (Mathematics) phone +1 917 742 8019 laserson@... ```
 Re: [Matplotlib-users] Path object where different vertices use different transforms? From: Jae-Joon Lee - 2009-09-29 03:28:43 ```> > Could you possibly explain exactly what is going on and how this > structurally differs from the approach that Mike posted? > > In Mike's code, he uses BboxTransformTo using the box he created in > display coords.  So this takes a unit square and spits out the box > that I specify when I instantiate the custom patch (using data coords > for x and y and axes coords for w).  What is called to actually draw > the box (i.e., when I execute plt.draw())?  Is that get_path()?  So > basically, whenever MPL wants to draw a patch, does it always call > get_path() and then runs it through whatever is returned from > get_transform() to get the final shape in display coords? Your understanding is basically right. When plt.draw(or any equivalent) is called, the draw methods of each artists are called. And the draw method of the Patch class, in general, calls the get_path and get_transform, while details can be different. > > So how does this relate to the strategy that you are advocating?  Is > _update_patch_transform somehow a synonym for what I described in the > paragraph above?  I don't know where that fits into the picture. > Yes, for the Rectangle class, its get_transform method returns a combined transform of patch_transform + default_artist_transform, where the patch_transform is used to transform the unit rectangle to the data coordinate. So, the basic idea is very similar to Mike's implementation, while Mike's should be more efficient as it transforms the unit rectangle directly to the canvas coordinate. > It may be useful to add something to the "Working With Tranformations" > section or the "Transformation Tutorial" about what is minimally > necessary to override for a custom patch.  I have been playing around > with MPL for some time now (albeit I don't have much computer > visualization/graphics experience) and still have only a fuzzy idea of > what order things are called in and what the overall > strategy/structure of the system is like. > Well, right now, I guess the source code is your best tutor (which was and still is for me). You may start with the mpatches.Patch that Mike's MyBox inherit from. And any contribution will be greatly appreciated! -JJ > Uri > >> >> -JJ >> >>> Uri >>> >>>> >>>> Mike >>>> >>>> Eric Firing wrote: >>>>> >>>>> Uri Laserson wrote: >>>>> >>>>>> >>>>>> Is it possible to specify a path object that will use different >>>>>> transforms for different vertices? >>>>>> >>>>>> This is again related to plotting a box whose height is specified by >>>>>> data coords, but whose width is a constant in axes coords regardless >>>>>> of scale (so linear and log x-scales would produce a box of the same >>>>>> width). >>>>>> >>>>>> Ideally, I would draw a path like this: >>>>>> 1. the center of the box would be located at x and bottom and top >>>>>> would be y1, y2, all in data coords >>>>>> 2. I would move to (x,y1) at the bottom-center of the box. >>>>>> 3. The x value would now need to be converted to Axes coords, possibly >>>>>> by applying transData + transAxes.inverted >>>>>> 4. I would want to draw a line to (x-0.1, y1) where x is now in axes >>>>>> coords and y is still in data coords.  Then up, then right, then down, >>>>>> and then close the polygon. >>>>>> >>>>>> How do I implement this? >>>>>> >>>>> >>>>> I must be missing something, because I still don't see why you can't do >>>>> all this very simply by using a PolyCollection, with the vertices in axes >>>>> coordinates and the offset in data coordinates. >>>>> >>>>> Eric >>>>> >>>>> >>>>>> >>>>>> As I mentioned before, a blended transform would allow me to make the >>>>>> moves i am interested in.  However, a change of scale would change the >>>>>> correspondence between data and axes coords, so the axes transform >>>>>> part of the blended axes would have to be recomputed everytime the >>>>>> scale changes based on where the (x,y1) point lands in the axes.  Is >>>>>> this correct? >>>>>> >>>>>> Any suggestions are welcome...thanks! >>>>>> >>>>>> Uri >>>>>> >>>>>> >>>>>> >>>>> >>>>> >>>>> >>>>> ------------------------------------------------------------------------------ >>>>> Come build with us! The BlackBerry® Developer Conference in SF, CA >>>>> is the only developer event you need to attend this year. Jumpstart your >>>>> developing skills, take BlackBerry mobile applications to market and stay >>>>> ahead of the curve. Join us from November 9-12, 2009. Register now! >>>>> http://p.sf.net/sfu/devconf >>>>> _______________________________________________ >>>>> Matplotlib-users mailing list >>>>> Matplotlib-users@... >>>>> https://lists.sourceforge.net/lists/listinfo/matplotlib-users >>>>> >>>> >>>> -- >>>> Michael Droettboom >>>> Science Software Branch >>>> Operations and Engineering Division >>>> Space Telescope Science Institute >>>> Operated by AURA for NASA >>>> >>>> >>> >>> >>> >>> -- >>> Uri Laserson >>> PhD Candidate, Biomedical Engineering >>> Harvard Medical School (Genetics) >>> Massachusetts Institute of Technology (Mathematics) >>> phone +1 917 742 8019 >>> laserson@... >>> >>> ------------------------------------------------------------------------------ >>> Come build with us! The BlackBerry® Developer Conference in SF, CA >>> is the only developer event you need to attend this year. Jumpstart your >>> developing skills, take BlackBerry mobile applications to market and stay >>> ahead of the curve. Join us from November 9-12, 2009. Register now! >>> http://p.sf.net/sfu/devconf >>> _______________________________________________ >>> Matplotlib-users mailing list >>> Matplotlib-users@... >>> https://lists.sourceforge.net/lists/listinfo/matplotlib-users >>> >> > > > > -- > Uri Laserson > PhD Candidate, Biomedical Engineering > Harvard Medical School (Genetics) > Massachusetts Institute of Technology (Mathematics) > phone +1 917 742 8019 > laserson@... > ```
 Re: [Matplotlib-users] Path object where different vertices use different transforms? From: Jae-Joon Lee - 2009-09-29 03:38:41 ```The exception will go away if you explicitly use np.array as below. box = np.array([[self.x, self.y1], [self.x, self.y2]]) However, note that Mike's example has x-center at 0. -JJ On Mon, Sep 28, 2009 at 6:41 PM, Uri Laserson wrote: > Hi Mike, > > This is definitely on the right track.  Thanks a lot for writing it > out.  When I change the view limits, indeed the width stays constant > while the height gets rescaled.  However, when I try to change to a > logarithmic axis, I get the following errors.  Again, excuse my > ignorance, but I am not sure where exactly the offense is and how to > fix it. > > > In [57]: ax.set_xscale('log') > > In [58]: plt.draw() > ERROR: An unexpected error occurred while tokenizing input > The following traceback may be corrupted or invalid > The error message is: ('EOF in multi-line statement', (568, 0)) > > ERROR: An unexpected error occurred while tokenizing input > The following traceback may be corrupted or invalid > The error message is: ('EOF in multi-line statement', (568, 0)) > > ERROR: An unexpected error occurred while tokenizing input > The following traceback may be corrupted or invalid > The error message is: ('EOF in multi-line statement', (568, 0)) > > --------------------------------------------------------------------------- > TypeError                                 Traceback (most recent call last) > > /Users/laserson/Desktop/ in () > > /Library/Frameworks/Python.framework/Versions/4.3.0/lib/python2.5/site-packages/matplotlib/pyplot.pyc > in draw() >    348 def draw(): >    349     'redraw the current figure' > --> 350     get_current_fig_manager().canvas.draw() >    351 >    352 @docstring.copy_dedent(Figure.savefig) > > /Library/Frameworks/Python.framework/Versions/4.3.0/lib/python2.5/site-packages/matplotlib/backends/backend_tkagg.pyc > in draw(self) >    213 >    214     def draw(self): > --> 215         FigureCanvasAgg.draw(self) >    216         tkagg.blit(self._tkphoto, self.renderer._renderer, colormode=2) >    217         self._master.update_idletasks() > > /Library/Frameworks/Python.framework/Versions/4.3.0/lib/python2.5/site-packages/matplotlib/backends/backend_agg.pyc > in draw(self) >    376 >    377         self.renderer = self.get_renderer() > --> 378         self.figure.draw(self.renderer) >    379 >    380     def get_renderer(self): > > /Library/Frameworks/Python.framework/Versions/4.3.0/lib/python2.5/site-packages/matplotlib/artist.pyc > in draw_wrapper(artist, renderer, *kl) >     53     def draw_wrapper(artist, renderer, *kl): >     54         before(artist, renderer) > ---> 55         draw(artist, renderer, *kl) >     56         after(artist, renderer) >     57 > > /Library/Frameworks/Python.framework/Versions/4.3.0/lib/python2.5/site-packages/matplotlib/figure.pyc > in draw(self, renderer) >    770 >    771         # render the axes > --> 772         for a in self.axes: a.draw(renderer) >    773 >    774         # render the figure text > > /Library/Frameworks/Python.framework/Versions/4.3.0/lib/python2.5/site-packages/matplotlib/artist.pyc > in draw_wrapper(artist, renderer, *kl) >     53     def draw_wrapper(artist, renderer, *kl): >     54         before(artist, renderer) > ---> 55         draw(artist, renderer, *kl) >     56         after(artist, renderer) >     57 > > /Library/Frameworks/Python.framework/Versions/4.3.0/lib/python2.5/site-packages/matplotlib/axes.pyc > in draw(self, renderer, inframe) >   1743 >   1744         for zorder, i, a in dsu: > -> 1745             a.draw(renderer) >   1746 >   1747         renderer.close_group('axes') > > /Library/Frameworks/Python.framework/Versions/4.3.0/lib/python2.5/site-packages/matplotlib/artist.pyc > in draw_wrapper(artist, renderer, *kl) >     53     def draw_wrapper(artist, renderer, *kl): >     54         before(artist, renderer) > ---> 55         draw(artist, renderer, *kl) >     56         after(artist, renderer) >     57 > > /Library/Frameworks/Python.framework/Versions/4.3.0/lib/python2.5/site-packages/matplotlib/patches.pyc > in draw(self, renderer) >    353 >    354         path = self.get_path() > --> 355         transform = self.get_transform() >    356         tpath = transform.transform_path_non_affine(path) >    357         affine = transform.get_affine() > > /Users/laserson/Desktop/testMyPatch.py in get_transform(self) >     22      box = [[self.x, self.y1], >     23             [self.x, self.y2]] > ---> 24      box = self.axes.transData.transform(box) >     25 >     26      # Get the width as a fraction of the axes width > > /Library/Frameworks/Python.framework/Versions/4.3.0/lib/python2.5/site-packages/matplotlib/transforms.pyc > in transform(self, points) >   1893     def transform(self, points): >   1894         return self._b.transform( > -> 1895             self._a.transform(points)) >   1896     transform.__doc__ = Transform.transform.__doc__ >   1897 > > /Library/Frameworks/Python.framework/Versions/4.3.0/lib/python2.5/site-packages/matplotlib/transforms.pyc > in transform(self, points) >   1721             x_points = x.transform(points)[:, 0:1] >   1722         else: > -> 1723             x_points = x.transform(points[:, 0]) >   1724             x_points = x_points.reshape((len(x_points), 1)) >   1725 > > TypeError: list indices must be integers > > > > On Mon, Sep 28, 2009 at 16:56, Michael Droettboom wrote: >> Is the attached sort of what you want?  It defines a custom rectangle by (x, >> w, y1, y2) and overrides the get_transform of the patch to update itself at >> draw time. >> >> Mike >> >> Uri Laserson wrote: >>> >>> On Mon, Sep 28, 2009 at 16:03, Michael Droettboom wrote: >>> >>>> >>>> If I understand correctly, the top and bottom of the box are in data >>>> coordinates, the x-center of the box is in data coordinates, only the >>>> width >>>> of the box is in axes coordinates.  Is that correct?  If so, a >>>> >>> >>> That's exactly correct. >>> >>> >>>> >>>> PolyCollection won't be able to do this (directly), since that would >>>> require >>>> both the width and height to be in axes coordinates. >>>> >>> >>> In principle, could you use a blended tranform for that?  Eitherway, I >>> don't think it would work, because the patch objects would be drawn to >>> specific Axes coords.  If the scale is changed (e.g, by switching to >>> log scale), then what would prompt the Axes coords to be recalculated? >>>  I was thinking earlier that I could compose the transData and >>> transAxes.inverse transforms to recalculate where the new Axes coord >>> should be, but Mike thought this approach would fail (though I'm still >>> not exactly sure why, no doubt because of my own ignorance). >>> >>> Uri >>> >>> >>>> >>>> Mike >>>> >>>> Eric Firing wrote: >>>> >>>>> >>>>> Uri Laserson wrote: >>>>> >>>>> >>>>>> >>>>>> Is it possible to specify a path object that will use different >>>>>> transforms for different vertices? >>>>>> >>>>>> This is again related to plotting a box whose height is specified by >>>>>> data coords, but whose width is a constant in axes coords regardless >>>>>> of scale (so linear and log x-scales would produce a box of the same >>>>>> width). >>>>>> >>>>>> Ideally, I would draw a path like this: >>>>>> 1. the center of the box would be located at x and bottom and top >>>>>> would be y1, y2, all in data coords >>>>>> 2. I would move to (x,y1) at the bottom-center of the box. >>>>>> 3. The x value would now need to be converted to Axes coords, possibly >>>>>> by applying transData + transAxes.inverted >>>>>> 4. I would want to draw a line to (x-0.1, y1) where x is now in axes >>>>>> coords and y is still in data coords.  Then up, then right, then down, >>>>>> and then close the polygon. >>>>>> >>>>>> How do I implement this? >>>>>> >>>>>> >>>>> >>>>> I must be missing something, because I still don't see why you can't do >>>>> all this very simply by using a PolyCollection, with the vertices in >>>>> axes >>>>> coordinates and the offset in data coordinates. >>>>> >>>>> Eric >>>>> >>>>> >>>>> >>>>>> >>>>>> As I mentioned before, a blended transform would allow me to make the >>>>>> moves i am interested in.  However, a change of scale would change the >>>>>> correspondence between data and axes coords, so the axes transform >>>>>> part of the blended axes would have to be recomputed everytime the >>>>>> scale changes based on where the (x,y1) point lands in the axes.  Is >>>>>> this correct? >>>>>> >>>>>> Any suggestions are welcome...thanks! >>>>>> >>>>>> Uri >>>>>> >>>>>> >>>>>> >>>>>> >>>>> >>>>> >>>>> ------------------------------------------------------------------------------ >>>>> Come build with us! The BlackBerry® Developer Conference in SF, CA >>>>> is the only developer event you need to attend this year. Jumpstart your >>>>> developing skills, take BlackBerry mobile applications to market and >>>>> stay >>>>> ahead of the curve. Join us from November 9-12, 2009. Register >>>>> now! >>>>> http://p.sf.net/sfu/devconf >>>>> _______________________________________________ >>>>> Matplotlib-users mailing list >>>>> Matplotlib-users@... >>>>> https://lists.sourceforge.net/lists/listinfo/matplotlib-users >>>>> >>>>> >>>> >>>> -- >>>> Michael Droettboom >>>> Science Software Branch >>>> Operations and Engineering Division >>>> Space Telescope Science Institute >>>> Operated by AURA for NASA >>>> >>>> >>>> >>> >>> >>> >>> >> >> -- >> Michael Droettboom >> Science Software Branch >> Operations and Engineering Division >> Space Telescope Science Institute >> Operated by AURA for NASA >> >> >> import numpy as np >> import matplotlib.pyplot as plt >> import matplotlib.patches as mpatches >> import matplotlib.transforms as mtransforms >> import matplotlib.path as mpath >> >> class MyBox(mpatches.Patch): >> >>   def __init__(self, x, w, y1, y2, **kwargs): >>      self.x = x >>      self.w = w >>      self.y1 = y1 >>      self.y2 = y2 >>      mpatches.Patch.__init__(self, **kwargs) >> >>   def get_path(self): >>      return mpath.Path.unit_rectangle() >> >>   def get_transform(self): >> >>      # Transform the data-relative values >>      box = [[self.x, self.y1], >>             [self.x, self.y2]] >>      box = self.axes.transData.transform(box) >> >>      # Get the width as a fraction of the axes width >>      w = self.w * self.axes.bbox.width / 2.0 >> >>      # Add it to the data-transformed coordinates >>      box[0][0] -= w >>      box[1][0] += w >> >>      return mtransforms.BboxTransformTo(mtransforms.Bbox(box)) >> >> fig = plt.figure() >> ax = fig.add_subplot(111) >> patch = MyBox(0, 0.1, 0.5, 1.5) >> ax.add_patch(patch) >> ax.set_xlim((-1, 1)) >> ax.set_ylim((0, 2)) >> >> plt.show() >> >> > > > > -- > Uri Laserson > PhD Candidate, Biomedical Engineering > Harvard Medical School (Genetics) > Massachusetts Institute of Technology (Mathematics) > phone +1 917 742 8019 > laserson@... > > ------------------------------------------------------------------------------ > Come build with us! The BlackBerry® Developer Conference in SF, CA > is the only developer event you need to attend this year. Jumpstart your > developing skills, take BlackBerry mobile applications to market and stay > ahead of the curve. Join us from November 9-12, 2009. Register now! > http://p.sf.net/sfu/devconf > _______________________________________________ > Matplotlib-users mailing list > Matplotlib-users@... > https://lists.sourceforge.net/lists/listinfo/matplotlib-users > ```
 Re: [Matplotlib-users] Path object where different vertices use different transforms? From: Uri Laserson - 2009-09-29 14:35:56 ```Thanks so much for all the help! If my effort will produce something nice, I'll forward it on... Uri On Mon, Sep 28, 2009 at 23:38, Jae-Joon Lee wrote: > The exception will go away if you explicitly use np.array as below. > >     box = np.array([[self.x, self.y1], >                     [self.x, self.y2]]) > > However, note that Mike's example has x-center at 0. > > -JJ > > > On Mon, Sep 28, 2009 at 6:41 PM, Uri Laserson wrote: >> Hi Mike, >> >> This is definitely on the right track.  Thanks a lot for writing it >> out.  When I change the view limits, indeed the width stays constant >> while the height gets rescaled.  However, when I try to change to a >> logarithmic axis, I get the following errors.  Again, excuse my >> ignorance, but I am not sure where exactly the offense is and how to >> fix it. >> >> >> In [57]: ax.set_xscale('log') >> >> In [58]: plt.draw() >> ERROR: An unexpected error occurred while tokenizing input >> The following traceback may be corrupted or invalid >> The error message is: ('EOF in multi-line statement', (568, 0)) >> >> ERROR: An unexpected error occurred while tokenizing input >> The following traceback may be corrupted or invalid >> The error message is: ('EOF in multi-line statement', (568, 0)) >> >> ERROR: An unexpected error occurred while tokenizing input >> The following traceback may be corrupted or invalid >> The error message is: ('EOF in multi-line statement', (568, 0)) >> >> --------------------------------------------------------------------------- >> TypeError                                 Traceback (most recent call last) >> >> /Users/laserson/Desktop/ in () >> >> /Library/Frameworks/Python.framework/Versions/4.3.0/lib/python2.5/site-packages/matplotlib/pyplot.pyc >> in draw() >>    348 def draw(): >>    349     'redraw the current figure' >> --> 350     get_current_fig_manager().canvas.draw() >>    351 >>    352 @docstring.copy_dedent(Figure.savefig) >> >> /Library/Frameworks/Python.framework/Versions/4.3.0/lib/python2.5/site-packages/matplotlib/backends/backend_tkagg.pyc >> in draw(self) >>    213 >>    214     def draw(self): >> --> 215         FigureCanvasAgg.draw(self) >>    216         tkagg.blit(self._tkphoto, self.renderer._renderer, colormode=2) >>    217         self._master.update_idletasks() >> >> /Library/Frameworks/Python.framework/Versions/4.3.0/lib/python2.5/site-packages/matplotlib/backends/backend_agg.pyc >> in draw(self) >>    376 >>    377         self.renderer = self.get_renderer() >> --> 378         self.figure.draw(self.renderer) >>    379 >>    380     def get_renderer(self): >> >> /Library/Frameworks/Python.framework/Versions/4.3.0/lib/python2.5/site-packages/matplotlib/artist.pyc >> in draw_wrapper(artist, renderer, *kl) >>     53     def draw_wrapper(artist, renderer, *kl): >>     54         before(artist, renderer) >> ---> 55         draw(artist, renderer, *kl) >>     56         after(artist, renderer) >>     57 >> >> /Library/Frameworks/Python.framework/Versions/4.3.0/lib/python2.5/site-packages/matplotlib/figure.pyc >> in draw(self, renderer) >>    770 >>    771         # render the axes >> --> 772         for a in self.axes: a.draw(renderer) >>    773 >>    774         # render the figure text >> >> /Library/Frameworks/Python.framework/Versions/4.3.0/lib/python2.5/site-packages/matplotlib/artist.pyc >> in draw_wrapper(artist, renderer, *kl) >>     53     def draw_wrapper(artist, renderer, *kl): >>     54         before(artist, renderer) >> ---> 55         draw(artist, renderer, *kl) >>     56         after(artist, renderer) >>     57 >> >> /Library/Frameworks/Python.framework/Versions/4.3.0/lib/python2.5/site-packages/matplotlib/axes.pyc >> in draw(self, renderer, inframe) >>   1743 >>   1744         for zorder, i, a in dsu: >> -> 1745             a.draw(renderer) >>   1746 >>   1747         renderer.close_group('axes') >> >> /Library/Frameworks/Python.framework/Versions/4.3.0/lib/python2.5/site-packages/matplotlib/artist.pyc >> in draw_wrapper(artist, renderer, *kl) >>     53     def draw_wrapper(artist, renderer, *kl): >>     54         before(artist, renderer) >> ---> 55         draw(artist, renderer, *kl) >>     56         after(artist, renderer) >>     57 >> >> /Library/Frameworks/Python.framework/Versions/4.3.0/lib/python2.5/site-packages/matplotlib/patches.pyc >> in draw(self, renderer) >>    353 >>    354         path = self.get_path() >> --> 355         transform = self.get_transform() >>    356         tpath = transform.transform_path_non_affine(path) >>    357         affine = transform.get_affine() >> >> /Users/laserson/Desktop/testMyPatch.py in get_transform(self) >>     22      box = [[self.x, self.y1], >>     23             [self.x, self.y2]] >> ---> 24      box = self.axes.transData.transform(box) >>     25 >>     26      # Get the width as a fraction of the axes width >> >> /Library/Frameworks/Python.framework/Versions/4.3.0/lib/python2.5/site-packages/matplotlib/transforms.pyc >> in transform(self, points) >>   1893     def transform(self, points): >>   1894         return self._b.transform( >> -> 1895             self._a.transform(points)) >>   1896     transform.__doc__ = Transform.transform.__doc__ >>   1897 >> >> /Library/Frameworks/Python.framework/Versions/4.3.0/lib/python2.5/site-packages/matplotlib/transforms.pyc >> in transform(self, points) >>   1721             x_points = x.transform(points)[:, 0:1] >>   1722         else: >> -> 1723             x_points = x.transform(points[:, 0]) >>   1724             x_points = x_points.reshape((len(x_points), 1)) >>   1725 >> >> TypeError: list indices must be integers >> >> >> >> On Mon, Sep 28, 2009 at 16:56, Michael Droettboom wrote: >>> Is the attached sort of what you want?  It defines a custom rectangle by (x, >>> w, y1, y2) and overrides the get_transform of the patch to update itself at >>> draw time. >>> >>> Mike >>> >>> Uri Laserson wrote: >>>> >>>> On Mon, Sep 28, 2009 at 16:03, Michael Droettboom wrote: >>>> >>>>> >>>>> If I understand correctly, the top and bottom of the box are in data >>>>> coordinates, the x-center of the box is in data coordinates, only the >>>>> width >>>>> of the box is in axes coordinates.  Is that correct?  If so, a >>>>> >>>> >>>> That's exactly correct. >>>> >>>> >>>>> >>>>> PolyCollection won't be able to do this (directly), since that would >>>>> require >>>>> both the width and height to be in axes coordinates. >>>>> >>>> >>>> In principle, could you use a blended tranform for that?  Eitherway, I >>>> don't think it would work, because the patch objects would be drawn to >>>> specific Axes coords.  If the scale is changed (e.g, by switching to >>>> log scale), then what would prompt the Axes coords to be recalculated? >>>>  I was thinking earlier that I could compose the transData and >>>> transAxes.inverse transforms to recalculate where the new Axes coord >>>> should be, but Mike thought this approach would fail (though I'm still >>>> not exactly sure why, no doubt because of my own ignorance). >>>> >>>> Uri >>>> >>>> >>>>> >>>>> Mike >>>>> >>>>> Eric Firing wrote: >>>>> >>>>>> >>>>>> Uri Laserson wrote: >>>>>> >>>>>> >>>>>>> >>>>>>> Is it possible to specify a path object that will use different >>>>>>> transforms for different vertices? >>>>>>> >>>>>>> This is again related to plotting a box whose height is specified by >>>>>>> data coords, but whose width is a constant in axes coords regardless >>>>>>> of scale (so linear and log x-scales would produce a box of the same >>>>>>> width). >>>>>>> >>>>>>> Ideally, I would draw a path like this: >>>>>>> 1. the center of the box would be located at x and bottom and top >>>>>>> would be y1, y2, all in data coords >>>>>>> 2. I would move to (x,y1) at the bottom-center of the box. >>>>>>> 3. The x value would now need to be converted to Axes coords, possibly >>>>>>> by applying transData + transAxes.inverted >>>>>>> 4. I would want to draw a line to (x-0.1, y1) where x is now in axes >>>>>>> coords and y is still in data coords.  Then up, then right, then down, >>>>>>> and then close the polygon. >>>>>>> >>>>>>> How do I implement this? >>>>>>> >>>>>>> >>>>>> >>>>>> I must be missing something, because I still don't see why you can't do >>>>>> all this very simply by using a PolyCollection, with the vertices in >>>>>> axes >>>>>> coordinates and the offset in data coordinates. >>>>>> >>>>>> Eric >>>>>> >>>>>> >>>>>> >>>>>>> >>>>>>> As I mentioned before, a blended transform would allow me to make the >>>>>>> moves i am interested in.  However, a change of scale would change the >>>>>>> correspondence between data and axes coords, so the axes transform >>>>>>> part of the blended axes would have to be recomputed everytime the >>>>>>> scale changes based on where the (x,y1) point lands in the axes.  Is >>>>>>> this correct? >>>>>>> >>>>>>> Any suggestions are welcome...thanks! >>>>>>> >>>>>>> Uri >>>>>>> >>>>>>> >>>>>>> >>>>>>> >>>>>> >>>>>> >>>>>> ------------------------------------------------------------------------------ >>>>>> Come build with us! The BlackBerry® Developer Conference in SF, CA >>>>>> is the only developer event you need to attend this year. Jumpstart your >>>>>> developing skills, take BlackBerry mobile applications to market and >>>>>> stay >>>>>> ahead of the curve. Join us from November 9-12, 2009. Register >>>>>> now! >>>>>> http://p.sf.net/sfu/devconf >>>>>> _______________________________________________ >>>>>> Matplotlib-users mailing list >>>>>> Matplotlib-users@... >>>>>> https://lists.sourceforge.net/lists/listinfo/matplotlib-users >>>>>> >>>>>> >>>>> >>>>> -- >>>>> Michael Droettboom >>>>> Science Software Branch >>>>> Operations and Engineering Division >>>>> Space Telescope Science Institute >>>>> Operated by AURA for NASA >>>>> >>>>> >>>>> >>>> >>>> >>>> >>>> >>> >>> -- >>> Michael Droettboom >>> Science Software Branch >>> Operations and Engineering Division >>> Space Telescope Science Institute >>> Operated by AURA for NASA >>> >>> >>> import numpy as np >>> import matplotlib.pyplot as plt >>> import matplotlib.patches as mpatches >>> import matplotlib.transforms as mtransforms >>> import matplotlib.path as mpath >>> >>> class MyBox(mpatches.Patch): >>> >>>   def __init__(self, x, w, y1, y2, **kwargs): >>>      self.x = x >>>      self.w = w >>>      self.y1 = y1 >>>      self.y2 = y2 >>>      mpatches.Patch.__init__(self, **kwargs) >>> >>>   def get_path(self): >>>      return mpath.Path.unit_rectangle() >>> >>>   def get_transform(self): >>> >>>      # Transform the data-relative values >>>      box = [[self.x, self.y1], >>>             [self.x, self.y2]] >>>      box = self.axes.transData.transform(box) >>> >>>      # Get the width as a fraction of the axes width >>>      w = self.w * self.axes.bbox.width / 2.0 >>> >>>      # Add it to the data-transformed coordinates >>>      box[0][0] -= w >>>      box[1][0] += w >>> >>>      return mtransforms.BboxTransformTo(mtransforms.Bbox(box)) >>> >>> fig = plt.figure() >>> ax = fig.add_subplot(111) >>> patch = MyBox(0, 0.1, 0.5, 1.5) >>> ax.add_patch(patch) >>> ax.set_xlim((-1, 1)) >>> ax.set_ylim((0, 2)) >>> >>> plt.show() >>> >>> >> >> >> >> -- >> Uri Laserson >> PhD Candidate, Biomedical Engineering >> Harvard Medical School (Genetics) >> Massachusetts Institute of Technology (Mathematics) >> phone +1 917 742 8019 >> laserson@... >> >> ------------------------------------------------------------------------------ >> Come build with us! The BlackBerry® Developer Conference in SF, CA >> is the only developer event you need to attend this year. Jumpstart your >> developing skills, take BlackBerry mobile applications to market and stay >> ahead of the curve. Join us from November 9-12, 2009. Register now! >> http://p.sf.net/sfu/devconf >> _______________________________________________ >> Matplotlib-users mailing list >> Matplotlib-users@... >> https://lists.sourceforge.net/lists/listinfo/matplotlib-users >> > -- Uri Laserson PhD Candidate, Biomedical Engineering Harvard Medical School (Genetics) Massachusetts Institute of Technology (Mathematics) phone +1 917 742 8019 laserson@... ```