Re: [matplotlib-devel] Scale independent drawing
Eric Firing wrote: Ryan May wrote: Hi, I'll continue my current flood of emails to the list. :) I'm finally getting back to my work on Skew-T plots, and I have a semi-working implementation (attached.) It runs, and as is, plots up some of the grid, with the x-value grid lines skewed 45 degrees to the right (as they should be.) The problem is as you resize the plot horizontally, some weird things happen. First, some of the lines that start overlaid end up separating as you expand the plot. The difference is between what is added using ax.plot and what is added using ax.vlines. The former adds Line2D objects while the latter adds a LineCollection which is holding path objects. I'm really not sure what's going on there. I'm not done checking it out yet, but I'm curious if anyone has any ideas off the top of their head. The second issue, which is more pressing, is when you resize vertically, the axes limits of the plot don't change (good), but unfortunately the lines don't stay connected to their lower y-coordinate in data space (bad). I'm really needing to draw things in a coordinate system that's independant of the data scale but also doesn't depend on the aspect ratio of the axes, so that I can get lines (and data plots) where the x gridlines are always at a 45 degree angle and the lower Y-value point stays fixed. By problem right now is that while I can find the lower left corner in pixel space and use that to do the proper adjustments, this changes when you resize. This changing is especially important in the y-direction. What I need is either of: 1) Axes space adjusted for aspect ratio (and updated with resizes) 2) Pixel space relative to some corner of the axes Or something similar that I don't know about. Any thoughts, or do I just need to come up with some magical combination of transforms that works? You can see what I have so far in my attached file. Ryan, based only on your description of the problems, and of what you need, I think the answer, or at least part of it, may be in good old quiver. Look at the way the transform is being generated depending on the units chosen, and note that preserving a specified angle on the page is part of it. Also note that the transform has to be regenerated on resize events, so a custom draw method is required. Ok, I've attached code that works for my purpose. It includes text data so that you can see what the plot is supposed to look like. It turned out to be rather simple once I figured out exactly what needed to happen and how the matplotlib API stacked up. As noted in the file, I still have much to do, like add proper gridlines and somehow fix the nastiness when you try to pan or zoom. I now at least have a plot that gives me what I want and resizes correctly (the fact that it looks weird to my meteorologist eyes when resized is a consequence of the transform's dependence on data ranges and physical size of the plot). I ended up going with an approach that just overrides draw to call a function to update the Axes.transData attribute. I also set transData to be a transformWrapper() so that any objects that grab the transform will have access the the updated transform when a resize occurs. BIG THANKS to Mike for creating such an awesome transform framework. Once you get the hang of the coordinate systems and know what's actually possible, it's *extremely* powerful. Now my bigger question is where the heck to put what I have when I'm finished... Ryan -- Ryan May Graduate Research Assistant School of Meteorology University of Oklahoma from matplotlib.axes import Axes from matplotlib.path import Path from matplotlib.lines import Line2D from matplotlib.ticker import Formatter, Locator, NullLocator, FixedLocator, \ NullFormatter, AutoLocator, ScalarFormatter from matplotlib import transforms from matplotlib.projections import register_projection import numpy as np #TODO: # *Panning and zooming are horribly broken, probably because the #skewed data are used as bounds. Needs to be disabled (especially panning) #or updated to work sensibly # *Gridlines for the x-axis need to be redone to use the skewed ones # *New functions/methods needed to add the various significant lines: # -Water vapor mixing ratio # -Dry adiabats # -Moist adiabats #Will these work as new kinds of gridlines? class SkewXAxes(Axes): # The projection must specify a name. This will be used be the # user to select the projection, i.e. ``subplot(111, # projection='skewx')``. name = 'skewx' def draw(self, *args): ''' draw() is overridden here to allow the data transform to be updated before calling the Axes.draw() method. This allows resizes to be properly handled without registering callbacks. The amount of work done here is kept to a minimum. ''' self._update_data_transform()
Re: [matplotlib-devel] Scale independent drawing
Ryan May wrote: Hi, I'll continue my current flood of emails to the list. :) I'm finally getting back to my work on Skew-T plots, and I have a semi-working implementation (attached.) It runs, and as is, plots up some of the grid, with the x-value grid lines skewed 45 degrees to the right (as they should be.) The problem is as you resize the plot horizontally, some weird things happen. First, some of the lines that start overlaid end up separating as you expand the plot. The difference is between what is added using ax.plot and what is added using ax.vlines. The former adds Line2D objects while the latter adds a LineCollection which is holding path objects. I'm really not sure what's going on there. I'm not done checking it out yet, but I'm curious if anyone has any ideas off the top of their head. The second issue, which is more pressing, is when you resize vertically, the axes limits of the plot don't change (good), but unfortunately the lines don't stay connected to their lower y-coordinate in data space (bad). I'm really needing to draw things in a coordinate system that's independant of the data scale but also doesn't depend on the aspect ratio of the axes, so that I can get lines (and data plots) where the x gridlines are always at a 45 degree angle and the lower Y-value point stays fixed. By problem right now is that while I can find the lower left corner in pixel space and use that to do the proper adjustments, this changes when you resize. This changing is especially important in the y-direction. What I need is either of: 1) Axes space adjusted for aspect ratio (and updated with resizes) 2) Pixel space relative to some corner of the axes Or something similar that I don't know about. Any thoughts, or do I just need to come up with some magical combination of transforms that works? You can see what I have so far in my attached file. Ryan, based only on your description of the problems, and of what you need, I think the answer, or at least part of it, may be in good old quiver. Look at the way the transform is being generated depending on the units chosen, and note that preserving a specified angle on the page is part of it. Also note that the transform has to be regenerated on resize events, so a custom draw method is required. (Mike D. translated my original quiver code to use his transforms framework.) It seems like there should be an easier-to-use and more general way to do these sorts of things, and maybe there is--or maybe it can be ginned up. This reminds me of a thread a long time ago regarding adding hooks so that classes could register methods to be executed before their artists are rendered but after things like window and axes sizes have been determined. Eric - This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK win great prizes Grand prize is a trip for two to an Open Source event anywhere in the world http://moblin-contest.org/redirect.php?banner_id=100url=/ ___ Matplotlib-devel mailing list Matplotlib-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/matplotlib-devel
Re: [matplotlib-devel] Scale independent drawing
On Tue, Jul 22, 2008 at 6:55 PM, Eric Firing [EMAIL PROTECTED] wrote: Ryan May wrote: Hi, I'll continue my current flood of emails to the list. :) I'm finally getting back to my work on Skew-T plots, and I have a semi-working implementation (attached.) It runs, and as is, plots up some of the grid, with the x-value grid lines skewed 45 degrees to the right (as they should be.) The problem is as you resize the plot horizontally, some weird things happen. First, some of the lines that start overlaid end up separating as you expand the plot. The difference is between what is added using ax.plot and what is added using ax.vlines. The former adds Line2D objects while the latter adds a LineCollection which is holding path objects. I'm really not sure what's going on there. I'm not done checking it out yet, but I'm curious if anyone has any ideas off the top of their head. The second issue, which is more pressing, is when you resize vertically, the axes limits of the plot don't change (good), but unfortunately the lines don't stay connected to their lower y-coordinate in data space (bad). I'm really needing to draw things in a coordinate system that's independant of the data scale but also doesn't depend on the aspect ratio of the axes, so that I can get lines (and data plots) where the x gridlines are always at a 45 degree angle and the lower Y-value point stays fixed. By problem right now is that while I can find the lower left corner in pixel space and use that to do the proper adjustments, this changes when you resize. This changing is especially important in the y-direction. What I need is either of: 1) Axes space adjusted for aspect ratio (and updated with resizes) 2) Pixel space relative to some corner of the axes Or something similar that I don't know about. Any thoughts, or do I just need to come up with some magical combination of transforms that works? You can see what I have so far in my attached file. Ryan, based only on your description of the problems, and of what you need, I think the answer, or at least part of it, may be in good old quiver. Look at the way the transform is being generated depending on the units chosen, and note that preserving a specified angle on the page is part of it. Also note that the transform has to be regenerated on resize events, so a custom draw method is required. (Mike D. translated my original quiver code to use his transforms framework.) It seems like there should be an easier-to-use and more general way to do these sorts of things, and maybe there is--or maybe it can be ginned up. This reminds me of a thread a long time ago regarding adding hooks so that classes could register methods to be executed before their artists are rendered but after things like window and axes sizes have been determined. Since I'm 1. A meteorologist and 2. responsible for the draw-hook thread, I see I'm implicated here :) The utility of the before/after draw hook comes in when you want to do something system wide on all draw events. If the SkewT needs to do some setup before the Axes draw, a simple override of draw() seems the better route, since the need here would be class specific. That said, I was inspired by this to add on a bit to my previous hook solution, but that belongs in a separate thread. -Eric B - This SF.Net email is sponsored by the Moblin Your Move Developer's challenge Build the coolest Linux based applications with Moblin SDK win great prizes Grand prize is a trip for two to an Open Source event anywhere in the world http://moblin-contest.org/redirect.php?banner_id=100url=/ ___ Matplotlib-devel mailing list Matplotlib-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/matplotlib-devel