## Re: [Matplotlib-users] How doyou draw in pixel or lenght units?

 Re: [Matplotlib-users] How doyou draw in pixel or lenght units? From: John Hunter - 2006-01-10 18:38:30 ```>>>>> "Christopher" == Christopher Barker writes: Christopher> I was afraid I'd have to do that. Do you have some Christopher> fairly simple sample code, that would help some. What you want to do is use a line collection, see http://matplotlib.sf.net/matplotlib.collections.py. You can specify a list of line segments which can be in one coordinate system (eg oriented lines with origin at 0 and lengths in points) and pass the collection a list off offsets which can be in another coordinate system (eg the locations of the lines in data coordinates). This is just the kinds of thing that is useful for a vector field, where you want oriented lines at x,y coords in data coords but lengths and orientation of the lines in some physical coordinate system. Here is a little example -- you'll also want to read up on mpl transforms at http://matplotlib.sf.net/matplotlib.transforms.html from matplotlib.transforms import scale_transform, Value from matplotlib.collections import LineCollection from pylab import figure, show import matplotlib.numerix as nx N = 100 angles = nx.mlab.rand(N)*2*nx.pi radii = nx.mlab.rand(N)*144. # max line should be 2 inches long segments = [((0,0), (r*nx.cos(theta), r*nx.sin(theta))) for r,theta in zip(radii, angles)] offsets = zip(10*nx.mlab.rand(N),20*nx.mlab.randn(N)) fig = figure() ax = fig.add_subplot(111) coll = LineCollection(segments, offsets=offsets, transOffset=ax.transData, # transforms the x,y offsets ) # points/72.*dpi = pixels -- see matplotlib.transforms trans = scale_transform(fig.dpi/Value(72.), fig.dpi/Value(72.)) coll.set_transform(trans) # the points to pixels transform ax.add_collection(coll) ax.set_xlim(0,10) ax.set_ylim(0,20) show() ```

 [Matplotlib-users] How doyou draw in pixel or lenght units? From: Christopher Barker - 2006-01-10 00:51:12 Attachments: junk.png ```Hi all, This is a re-post, which I don't' ordinarily do, but I got not a single reply, so I wonder if it never actually got posted. I'm trying to figure out how to draw something in pixel or "real" units(inches, mm, etc). what I want is to be able to place an object according to axes units, but not have it change size as I zoom in and out, kind of like a marker. The big picture: I'm trying to make a plot that shows a vector value over time (in this case ocean current velocity and direction). The x axis is time, the y axis is magnitude, and at each point I want to draw an arrow pointing in the direction of the vector at that time. However, I don't want the size (or angle) of that arrow to change as you zoom in and out. Any ideas how I can accomplish this? See the enclosed PNG for an example with fake data. -Chris -- Christopher Barker, Ph.D. Oceanographer NOAA/OR&R/HAZMAT (206) 526-6959 voice 7600 Sand Point Way NE (206) 526-6329 fax Seattle, WA 98115 (206) 526-6317 main reception Chris.Barker@... -- Christopher Barker, Ph.D. Oceanographer NOAA/OR&R/HAZMAT (206) 526-6959 voice 7600 Sand Point Way NE (206) 526-6329 fax Seattle, WA 98115 (206) 526-6317 main reception Chris.Barker@... ```
 Re: [Matplotlib-users] How doyou draw in pixel or lenght units? From: Eric Firing - 2006-01-10 17:55:42 ```Chris, Your previous post did get through. This is something that I will need also, and I would like to look into it, but I haven't been able to find the time yet. I have worked on this sort of thing in Matlab--I added the vector-plotting capability (m_vec) to Rich Pawlowicz's m_map package. (I realize that what you are talking about is a little bit different from what m_vec does, but it requires the same type of control over how plotting is done.) My guess is that in the long run it will be possible to do it much more easily and directly in mpl than in Matlab, but this may require some modifications or additions to mpl internals. Eric Christopher Barker wrote: > Hi all, > > This is a re-post, which I don't' ordinarily do, but I got not a single > reply, so I wonder if it never actually got posted. > > I'm trying to figure out how to draw something in pixel or "real" > units(inches, mm, etc). what I want is to be able to place an object > according to axes units, but not have it change size as I zoom in and > out, kind of like a marker. > > The big picture: > > I'm trying to make a plot that shows a vector value over time (in this > case ocean current velocity and direction). The x axis is time, the y > axis is magnitude, and at each point I want to draw an arrow pointing in > the direction of the vector at that time. However, I don't want the size > (or angle) of that arrow to change as you zoom in and out. > > Any ideas how I can accomplish this? > > See the enclosed PNG for an example with fake data. > > -Chris > > > > > ------------------------------------------------------------------------ > ```
 Re: [Matplotlib-users] How doyou draw in pixel or lenght units? From: Christopher Barker - 2006-01-10 18:05:24 ```Rich Shepard wrote: > Have you looked at PSTricks? I haven't looked at that for ages. I need this in a wxPython app, as well as other formats, so MPL only would be nice. > I know that it can draw this type of plot > from real data in a file, and I suspect that once you define the arrows as going > from one point to another, that's how they'll stay. If the spacing between > those points varies with the size of the image, I don't know of any > application that will automatically recalculate each vector and keep it a > fixed length. actually, it's the other way around in a way: the application has to re-calculate the data to make the length change. After all the actual drawing happens in pixel coordinates. > All the 2D drawing/plotting programs I've used (e.g., Gri, > tgif, jpicedt, PSTricks, ipe) Yes and no. In MPL, and others, some things are fixed: text size, markers, etc. In this case, what I want is really like a marker, except that each marker needs to be rotated differently. The PNG I enclosed was generated with my wxPython FloatCanvas. I designed that to present data graphically in arbitrary coordinates, and it felt very natural to have objects that done' scale as you zoom: text, dots, bitmaps, line widths, etc, etc. I also have scalable objects. However, I haven't written code to handle axes, etc, so I prefer to use MPL for traditional plotting. Hugo Gamboa wrote: > I'm quite new to matplotlib, and I had a problem with zooming, and I > solved it by catching the draw event, obtain the new axis, recalculate > the data and presenting it again. I was afraid I'd have to do that. Do you have some fairly simple sample code, that would help some. I'm also going to dig into how markers are done. maybe I can leverage that somehow. What I'm hoping to find is a way to define a new patch or something, that can draw in pixel (or pt) units at a location in axes coordinates. Maybe I'm just stuck thinking about it in that way because of how I've written my code, but it seems useful. I'd be interested in what John thinks about this: -- is there an easy way to do this? -- If not, do you thing it would be worth adding? Are you reading, John? thanks, -Chris -- Christopher Barker, Ph.D. Oceanographer NOAA/OR&R/HAZMAT (206) 526-6959 voice 7600 Sand Point Way NE (206) 526-6329 fax Seattle, WA 98115 (206) 526-6317 main reception Chris.Barker@... ```
 Re: [Matplotlib-users] How doyou draw in pixel or lenght units? From: John Hunter - 2006-01-10 18:38:30 ```>>>>> "Christopher" == Christopher Barker writes: Christopher> I was afraid I'd have to do that. Do you have some Christopher> fairly simple sample code, that would help some. What you want to do is use a line collection, see http://matplotlib.sf.net/matplotlib.collections.py. You can specify a list of line segments which can be in one coordinate system (eg oriented lines with origin at 0 and lengths in points) and pass the collection a list off offsets which can be in another coordinate system (eg the locations of the lines in data coordinates). This is just the kinds of thing that is useful for a vector field, where you want oriented lines at x,y coords in data coords but lengths and orientation of the lines in some physical coordinate system. Here is a little example -- you'll also want to read up on mpl transforms at http://matplotlib.sf.net/matplotlib.transforms.html from matplotlib.transforms import scale_transform, Value from matplotlib.collections import LineCollection from pylab import figure, show import matplotlib.numerix as nx N = 100 angles = nx.mlab.rand(N)*2*nx.pi radii = nx.mlab.rand(N)*144. # max line should be 2 inches long segments = [((0,0), (r*nx.cos(theta), r*nx.sin(theta))) for r,theta in zip(radii, angles)] offsets = zip(10*nx.mlab.rand(N),20*nx.mlab.randn(N)) fig = figure() ax = fig.add_subplot(111) coll = LineCollection(segments, offsets=offsets, transOffset=ax.transData, # transforms the x,y offsets ) # points/72.*dpi = pixels -- see matplotlib.transforms trans = scale_transform(fig.dpi/Value(72.), fig.dpi/Value(72.)) coll.set_transform(trans) # the points to pixels transform ax.add_collection(coll) ax.set_xlim(0,10) ax.set_ylim(0,20) show() ```
 Re: [Matplotlib-users] How doyou draw in pixel or lenght units? From: Christopher Barker - 2006-01-26 17:26:48 Attachments: VectorPlot.png VecPlot.py ```Hi all, I've written a little custom LineCollection class that draws a bunch of arrows pointing in given directions, with their origins at a set of (x,y) points. I use this type of plot to plot vector quantities varying over time, like an ocean current at a point, for instance. The x-axis is time, the y-axis is magnitude, and the arrow points in the direction. I've enclosed a PNG of a sample plot (with clearly meaningless data), and the code that created it. John Hunter wrote: > What you want to do is use a line collection, Following John's sample code, I got it working, but I do have a few questions: I'm now drawing the arrows as a LineCollection, and then drawing with 'o' markers on top to get the circles. Is there a way to add markers like that to the LineCollection, so that it's a single class? The arrow heads look a bit off. If you make them much larger, they look fine, but small, they're not quire right. I suspect there is some rounding to integers that is going on. Or maybe it's something with the join style? (note, I'm using GTKAgg) The way the code is written now, I need to pass in a axes object and a figure object, as I need the transData attribute from the axes and the dpi attribute from the figure. This creates a coupling that I'm not happy with. It's a bit odd that I have to pass the axes into the constructor, then add the LineCollection to the axes again. Is there a way to write this so that the transOffset and transform are applied when the LineCollection is added to the axes, rather than ahead of time? Also, the Figure coupling is even worse -- is there a way to discover what figure an axes is on from the axes itself (or get it's dpi, which is all I really need?) I guess what I'm hoping exists, and suggesting if it doesn't, is that the scaling and all would be "lazy", like lazy Values. The transform and scaling wouldn't be defined until it's time to actually render the LineCollection. I did something like that in my FloatCanvas. Each DrawObject has a _Draw method that gets a "WorldToPixel" function passed in. This function converts world coordinates that the object is defined in to pixel coordinates that it needs to draw itself with. That way, the object can exist entirely separate from a Canvas, and need know nothing about how it's coordinates need to be transformed until it needs to draw itself. Can something like this be done in MPL? Would this be a useful plot type to add to MPL? If so, can you suggest an existing class that I should imitate to define what the interface would look like? thanks, -Chris -- Christopher Barker, Ph.D. Oceanographer NOAA/OR&R/HAZMAT (206) 526-6959 voice 7600 Sand Point Way NE (206) 526-6329 fax Seattle, WA 98115 (206) 526-6317 main reception Chris.Barker@... ```
 Re: [Matplotlib-users] How doyou draw in pixel or lenght units? From: Fernando Perez - 2006-01-26 17:55:52 ```Christopher Barker wrote: > Hi all, > > I've written a little custom LineCollection class that draws a bunch of > arrows pointing in given directions, with their origins at a set of > (x,y) points. I use this type of plot to plot vector quantities varying > over time, like an ocean current at a point, for instance. The x-axis is > time, the y-axis is magnitude, and the arrow points in the direction. the code behind this: http://bayes.colorado.edu/cgi-bin/arrows/arrow_cgi.py (just try the mock example with the data in the page) is coming to matplotlib in a week or two. I think it addresses some of the issues you're dealing with: it's an arrows-on-steroids class, with control over heads (including the half-heads shown) and more. Cheers, f ```
 Re: [Matplotlib-users] How doyou draw in pixel or lenght units? From: Christopher Barker - 2006-01-26 19:47:07 ```Fernando Perez wrote: > the code behind this: > > http://bayes.colorado.edu/cgi-bin/arrows/arrow_cgi.py > > (just try the mock example with the data in the page) is coming to > matplotlib in a week or two. Now you tell me! Would you be willing to send me some code sooner? I don't want to work on my code more it you've already done a better job of it. Did you make a "Collections" class. I can imagine that performance could be important sometimes. -Chris -- Christopher Barker, Ph.D. Oceanographer NOAA/OR&R/HAZMAT (206) 526-6959 voice 7600 Sand Point Way NE (206) 526-6329 fax Seattle, WA 98115 (206) 526-6317 main reception Chris.Barker@... ```
 Re: [Matplotlib-users] How doyou draw in pixel or lenght units? From: Fernando Perez - 2006-01-26 21:48:52 ```Christopher Barker wrote: > Fernando Perez wrote: > >>the code behind this: >> >>http://bayes.colorado.edu/cgi-bin/arrows/arrow_cgi.py >> >>(just try the mock example with the data in the page) is coming to >>matplotlib in a week or two. > > > Now you tell me! > > Would you be willing to send me some code sooner? I don't want to work > on my code more it you've already done a better job of it. > > Did you make a "Collections" class. I can imagine that performance could > be important sometimes. I didn't write the code, so I can't send it. I'll contact the author and let him know. Cheers, f ```
 Re: [Matplotlib-users] How doyou draw in pixel or lenght units? From: Christopher Barker - 2006-01-10 21:56:25 ```John Hunter wrote: > What you want to do is use a line collection, see John, you're fabulous, thanks. I think that's just what I was looking for. I figured that MPL would be designed in a way that this should be doable. -Chris -- Christopher Barker, Ph.D. Oceanographer NOAA/OR&R/HAZMAT (206) 526-6959 voice 7600 Sand Point Way NE (206) 526-6329 fax Seattle, WA 98115 (206) 526-6317 main reception Chris.Barker@... ```