Scale independent drawing

Hi,

I'll continue my current flood of emails to the list. :slight_smile: 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.

Thanks in advance,

Ryan

skewt2.py (4.74 KB)

路路路

--
Ryan May
Graduate Research Assistant
School of Meteorology
University of Oklahoma

Ryan May wrote:

Hi,

I'll continue my current flood of emails to the list. :slight_smile: 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

Eric Firing wrote:

Ryan May wrote:

Hi,

I'll continue my current flood of emails to the list. :slight_smile: 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.

I'll take a look and see what I come up with, thanks for the tip.

(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.

That's kind of what I was thinking and hoping. I would think this would be useful in a lot of places, especially where orientation relative to the screen is important, since that's not preserved when the axes are resized.

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.

Yeah it seems like this comes up a lot. What would be nice though, instead of hooks, would be to fetch the necessary values when the transform is actually needed, instead of being notified of when the transform itself needs to be regenerated. Notifications would seem to add needless boilerplate code.

Ryan

路路路

--
Ryan May
Graduate Research Assistant
School of Meteorology
University of Oklahoma

Since I'm 1. A meteorologist and 2. responsible for the draw-hook
thread, I see I'm implicated here :slight_smile:

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

路路路

On Tue, Jul 22, 2008 at 6:55 PM, Eric Firing <efiring@...229...> wrote:

Ryan May wrote:

Hi,

I'll continue my current flood of emails to the list. :slight_smile: 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 Firing wrote:

Ryan May wrote:

Hi,

I'll continue my current flood of emails to the list. :slight_smile: 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

skewt.py (10.7 KB)

路路路

--
Ryan May
Graduate Research Assistant
School of Meteorology
University of Oklahoma