(Wind) Barbs

Hi,

I've got (what seems to me) a nice clean, self-contained implementation of wind barbs plots. I'd like to see if I can get this into matplotlib, as it would be very useful to the meteorology community. I've borrowed heavily from Quiver for rounding out rough edges (like multiple calling signatures) as for templates for documentation. The base implementation, though, seems much simpler (thanks to Mike's transforms) and is based more on scatter.

Right now it monkey-patches Axes so that it can be a stand-alone file. Just running the file should give a good example of the expected output.

My only concern up front is if a new axes method is appropriate, since this is somewhat domain specific. But I'd like to at least get the new Collections class included, since otherwise, I have no idea how to get this distributed to the community at large.

I welcome any comments/criticism to help improve this.

Ryan

barbs.py (12.1 KB)

···

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

Hey Ryan,

I have looked at this code briefly and have a few minor comments. I
think Eric, who did the bulk of the current quiver implementation, and
as an oceanographer is in a field much closer to yours than mine, will
provide more useful feedback and should ultimately handle the patch
submission.

My first comment is that the code looks very good -- it is well
thought out and commented, and t is definitely suitable for inclusion
in the main line. Certainly the Barbs class can live in the
collections module. You note in the driver code that you are worried
about pollution of the axes namespace by including a domain specific
method, and this is a reasonable worry, but the axes namespace is
currently so polluted with plotting methods that it is a small worry.
I think it would be fine for you to rework your code into a patch
which provides the Barbs collection in matplotlib.collections, an Axes
method, and a pyplot interface function (with a pylab module level
docstring entry). The overloading of the Axes namespace is not ideal,
but it's what we've got.

My second comment has to do with your comment at the end of the example:

     #Showing colormapping with uniform grid. Unfortunately, only the flags
     #on barbs get colormapped this way.

On a cursory read of the code, it looks like you have implemented
everything as a single poly collection, and the reason the flags only
get colored is that the varicolored is black. It seems like there are
two solutions: write your class as a combination of poly collection
(for the flags) and line collection (for the barbs) and colormap both
(there are some line collection colormapping examples in the examples
subdir courtesy of Eric). The 2nd alternative, which I haven't
explored, is to set the edgecolor equal to the facecolor and support
colormapping of the edgecolors.

Overall this is very promising, and I wish you the best trying to make
mpl serviceble to the meteorology community. Jeff Whitaker has done a
phenomenal job with basemap providing extensions for those needing
cartographic projections as a toolkit. Depending on how far you want
to go with meteorological support, we can include the changes in the
mainline or fold them into a toolkit if they become hyper-specialized.

JDH

···

On Tue, Jul 15, 2008 at 5:37 PM, Ryan May <rmay31@...149...> wrote:

I welcome any comments/criticism to help improve this.

John Hunter wrote:

  The 2nd alternative, which I haven't
explored, is to set the edgecolor equal to the facecolor and support
colormapping of the edgecolors.
  

FWIW, pcolor and pcolormesh have also needed this functionality, and they do so in a somewhat hackish way. It would be nice (if barbs goes this way) to move that up into the Collections class and reuse it everywhere that needs it.

Mike

···

On Tue, Jul 15, 2008 at 5:37 PM, Ryan May <rmay31@...149...> wrote:

Ryan May wrote:

Hi,

I've got (what seems to me) a nice clean, self-contained implementation of wind barbs plots. I'd like to see if I can get this into matplotlib, as it would be very useful to the meteorology community. I've borrowed heavily from Quiver for rounding out rough edges (like multiple calling signatures) as for templates for documentation. The base implementation, though, seems much simpler (thanks to Mike's transforms) and is based more on scatter.

Right now it monkey-patches Axes so that it can be a stand-alone file. Just running the file should give a good example of the expected output.

My only concern up front is if a new axes method is appropriate, since this is somewhat domain specific. But I'd like to at least get the new Collections class included, since otherwise, I have no idea how to get this distributed to the community at large.

I welcome any comments/criticism to help improve this.

Ryan

Ryan: This looks great! I fixed one typo (the "length" keyword was mis-identified as "scale" in the docstring) and replace your example with an adaption of the quiver_demo.py basemap example.

I noticed that ticks on the barbs are so close that they are hard to discern unless the linewidth is reduced. I wonder if the spacing of the ticks could be added as a keyword, perhaps as a fraction of the wind barb length?

This will be a wonderful addition to matplotlib. Thanks!

-Jeff

P.S. eagerly awaiting your Skew-T implementation ....

barbs.py (13.4 KB)

···

--
Jeffrey S. Whitaker Phone : (303)497-6313
Meteorologist FAX : (303)497-6449
NOAA/OAR/PSD R/PSD1 Email : Jeffrey.S.Whitaker@...236...
325 Broadway Office : Skaggs Research Cntr 1D-113
Boulder, CO, USA 80303-3328 Web : Jeffrey S. Whitaker: NOAA Physical Sciences Laboratory

John Hunter wrote:

I welcome any comments/criticism to help improve this.

Hey Ryan,

I have looked at this code briefly and have a few minor comments. I
think Eric, who did the bulk of the current quiver implementation, and
as an oceanographer is in a field much closer to yours than mine, will
provide more useful feedback and should ultimately handle the patch
submission.

My first comment is that the code looks very good -- it is well
thought out and commented, and t is definitely suitable for inclusion
in the main line. Certainly the Barbs class can live in the
collections module. You note in the driver code that you are worried
about pollution of the axes namespace by including a domain specific
method, and this is a reasonable worry, but the axes namespace is
currently so polluted with plotting methods that it is a small worry.
I think it would be fine for you to rework your code into a patch
which provides the Barbs collection in matplotlib.collections, an Axes
method, and a pyplot interface function (with a pylab module level
docstring entry). The overloading of the Axes namespace is not ideal,
but it's what we've got.

Thanks. My question then is how do I add a pyplot interface, since it appears from the comments that many of those are just generated boilerplate?

My second comment has to do with your comment at the end of the example:

     #Showing colormapping with uniform grid. Unfortunately, only the flags
     #on barbs get colormapped this way.

On a cursory read of the code, it looks like you have implemented
everything as a single poly collection, and the reason the flags only
get colored is that the varicolored is black. It seems like there are
two solutions: write your class as a combination of poly collection
(for the flags) and line collection (for the barbs) and colormap both
(there are some line collection colormapping examples in the examples
subdir courtesy of Eric). The 2nd alternative, which I haven't
explored, is to set the edgecolor equal to the facecolor and support
colormapping of the edgecolors.

Yeah, the comment went more to explain expected results. There was no mystery to me why the edgecolors didn't get colormapped, it was pretty clear from the collections code. I had started down the road of combining lines and polygons in a PatchCollection, but that created a bunch of separate objects for each wind barb that had to each be transformed and have an offset applied. I took the lazy way out and created (admittedly) degenerate polygons. :slight_smile: I hadn't actually thought (call it a brain fart) about actually going ahead and adding colormapping for the edgecolors. Should I follow Mike's suggestion and possibly take a go at adding it to the general Collections class? (Granted, if someone else took a stab at it, it might land in SVN sooner, I'm sure I still have a learning curve to go here).

Overall this is very promising, and I wish you the best trying to make
mpl serviceble to the meteorology community. Jeff Whitaker has done a
phenomenal job with basemap providing extensions for those needing
cartographic projections as a toolkit. Depending on how far you want
to go with meteorological support, we can include the changes in the
mainline or fold them into a toolkit if they become hyper-specialized.

I still have a few more things to add (on top of what Whitaker already fixed for me):

* Need to plot something (empty circle) for vector magnitude < 5. (I did a plot the other day and was befuddled for a bit by seeing only 6 barbs)
* Need to fix support for masked arrays. The way the iteration goes right now, masked values end up being iterated over, which is bad.
* Probably should add a set_uv(c) method, like quiver

We'll see about the possibility of a toolkit. If I can keep up the momentum, I might end up with significant functionality. I'd also have to see how much of it really ends up being more than just simple example scripts. And I agree, huge props to Whitaker for Basemap. Hopefully I can get more people around me to use it instead of the abominations used now. :slight_smile:

(I'd have things sooner if it weren't for the stupid Google CodeJam :slight_smile: )

Ryan

···

On Tue, Jul 15, 2008 at 5:37 PM, Ryan May <rmay31@...149...> wrote:

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

Jeff Whitaker wrote:

Ryan May wrote:

Hi,

I've got (what seems to me) a nice clean, self-contained implementation of wind barbs plots. I'd like to see if I can get this into matplotlib, as it would be very useful to the meteorology community. I've borrowed heavily from Quiver for rounding out rough edges (like multiple calling signatures) as for templates for documentation. The base implementation, though, seems much simpler (thanks to Mike's transforms) and is based more on scatter.

Right now it monkey-patches Axes so that it can be a stand-alone file. Just running the file should give a good example of the expected output.

My only concern up front is if a new axes method is appropriate, since this is somewhat domain specific. But I'd like to at least get the new Collections class included, since otherwise, I have no idea how to get this distributed to the community at large.

I welcome any comments/criticism to help improve this.

Ryan

Ryan: This looks great! I fixed one typo (the "length" keyword was mis-identified as "scale" in the docstring) and replace your example with an adaption of the quiver_demo.py basemap example.

Thanks. When this finally lands in matplotlib svn, do you need me to do the patch to add it to basemap? If so, anything I should know? Or will you just take care of it?

I noticed that ticks on the barbs are so close that they are hard to discern unless the linewidth is reduced. I wonder if the spacing of the ticks could be added as a keyword, perhaps as a fraction of the wind barb length?

It's already coded up as such, it's just a matter of exposing it as a keyword. I didn't do it already because I didn't want the alphabet soup. But I guess since I'm already parsing the **kw dictionary, popping off a few more values isn't too bad...

This will be a wonderful addition to matplotlib. Thanks!

-Jeff

P.S. eagerly awaiting your Skew-T implementation ....

You and every other met I know...It's a good thing I want this so badly, because having struggled with it I understand why there's so few implementations out there. Wind barbs actually came as a nice little distraction to learn a bit of the matplotlib API before trying to get the Skew-T right again.

Ryan

···

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

Ryan May wrote:

John Hunter wrote:

I welcome any comments/criticism to help improve this.

Hey Ryan,

I have looked at this code briefly and have a few minor comments. I
think Eric, who did the bulk of the current quiver implementation, and
as an oceanographer is in a field much closer to yours than mine, will
provide more useful feedback and should ultimately handle the patch
submission.

I would be happy to do so.

My first comment is that the code looks very good -- it is well
thought out and commented, and t is definitely suitable for inclusion
in the main line. Certainly the Barbs class can live in the
collections module. You note in the driver code that you are worried
about pollution of the axes namespace by including a domain specific
method, and this is a reasonable worry, but the axes namespace is
currently so polluted with plotting methods that it is a small worry.
I think it would be fine for you to rework your code into a patch
which provides the Barbs collection in matplotlib.collections, an Axes
method, and a pyplot interface function (with a pylab module level
docstring entry). The overloading of the Axes namespace is not ideal,
but it's what we've got.

Thanks. My question then is how do I add a pyplot interface, since it appears from the comments that many of those are just generated boilerplate?

If all that is needed is a standard wrapper, then you add an entry to the appropriate list in boilerplate.py (which is in the root mpl directory, alongside CHANGELOG etc.), and run it to generate all the boilerplate, and then substitute that output for the corresponding chunk at the end of pyplot.py. (Or do some variation on this procedure that gives the same end result.)

My second comment has to do with your comment at the end of the example:

     #Showing colormapping with uniform grid. Unfortunately, only the flags
     #on barbs get colormapped this way.

On a cursory read of the code, it looks like you have implemented
everything as a single poly collection, and the reason the flags only
get colored is that the varicolored is black. It seems like there are
two solutions: write your class as a combination of poly collection
(for the flags) and line collection (for the barbs) and colormap both
(there are some line collection colormapping examples in the examples
subdir courtesy of Eric). The 2nd alternative, which I haven't
explored, is to set the edgecolor equal to the facecolor and support
colormapping of the edgecolors.

Isn't this already done? Here is a Collections method:

     def set_edgecolor(self, c):
         """
         Set the edgecolor(s) of the collection. *c* can be a
         matplotlib color arg (all patches have same color), or a
         sequence or rgba tuples; if it is a sequence the patches will
         cycle through the sequence.

         If *c* is 'face', the edge color will always be the same as
         the face color.

         ACCEPTS: matplotlib color arg or sequence of rgba tuples
         """
         if c == 'face':
             self._edgecolors = 'face'
         else:
             if c is None: c = mpl.rcParams['patch.edgecolor']
             self._edgecolors = _colors.colorConverter.to_rgba_array(c, self._alpha)

And in the draw method:

         if self._edgecolors == 'face':
             edgecolors = self._facecolors
         else:
             edgecolors = self._edgecolors

         renderer.draw_path_collection(
             transform.frozen(), self.clipbox, clippath, clippath_trans,
             paths, self.get_transforms(),
             offsets, transOffset,
             self._facecolors, edgecolors, self._linewidths,
             self._linestyles, self._antialiaseds)

Am I missing something? (Probably--I have not looked very closely at barb yet.)

Eric

···

On Tue, Jul 15, 2008 at 5:37 PM, Ryan May <rmay31@...149...> wrote:

Yeah, the comment went more to explain expected results. There was no mystery to me why the edgecolors didn't get colormapped, it was pretty clear from the collections code. I had started down the road of combining lines and polygons in a PatchCollection, but that created a bunch of separate objects for each wind barb that had to each be transformed and have an offset applied. I took the lazy way out and created (admittedly) degenerate polygons. :slight_smile: I hadn't actually thought (call it a brain fart) about actually going ahead and adding colormapping for the edgecolors. Should I follow Mike's suggestion and possibly take a go at adding it to the general Collections class? (Granted, if someone else took a stab at it, it might land in SVN sooner, I'm sure I still have a learning curve to go here).

Overall this is very promising, and I wish you the best trying to make
mpl serviceble to the meteorology community. Jeff Whitaker has done a
phenomenal job with basemap providing extensions for those needing
cartographic projections as a toolkit. Depending on how far you want
to go with meteorological support, we can include the changes in the
mainline or fold them into a toolkit if they become hyper-specialized.

I still have a few more things to add (on top of what Whitaker already fixed for me):

* Need to plot something (empty circle) for vector magnitude < 5. (I did a plot the other day and was befuddled for a bit by seeing only 6 barbs)
* Need to fix support for masked arrays. The way the iteration goes right now, masked values end up being iterated over, which is bad.
* Probably should add a set_uv(c) method, like quiver

We'll see about the possibility of a toolkit. If I can keep up the momentum, I might end up with significant functionality. I'd also have to see how much of it really ends up being more than just simple example scripts. And I agree, huge props to Whitaker for Basemap. Hopefully I can get more people around me to use it instead of the abominations used now. :slight_smile:

(I'd have things sooner if it weren't for the stupid Google CodeJam :slight_smile: )

Ryan