Basemap & ax parameter : bug or feature ?

Pierre GM wrote:

Pierre: The reason I did it that way was so that the basemap instance could be created independent of any axes instances. For instance, you can create a basemap instance before an axes instance is created, or you read in a basemap instance from a pickle. If a axes instance is associated with a Basemap instance, you can't save it in a pickle.

I understand that, I use pickled basemaps all the time. It's a great feature, by the way, thanks a lot.

If I understand you correctly, you are suggesting that when the basemap instance is created, the "ax" attribute be set to plt.gca() if no axes instance is passed in through the kwarg, instead of just setting it to None.
In that case, an axes instance will be created and assigned to the Basemap instance if one doesn't already exist.

That's the gist of it, yes. My point is that as soon something is drawn, the basemap should be linked to an Axes instance. The link could be overwritten later.

I guess I don't see any compelling reason for that, since you can always assign an axes instance to the Basemap instance later (via "map.ax = plt.gca()".
I'd rather have this done explicitly by the user, than have it happen automatically, with potentially surprising results.

Well, talking about surprising results, the experience I was relating in the original message: I load a basemap from a pickle, plot some contours on it (therefore, a new Axes is created), add a colorbar (a second Axes is created) and then draw a mapscale. I expect the mapscale to be drawn on the axes associated with the basemap, because I'm using one of the basemap's methods to plot the mapscale. With the current implementation, the scale gets drawn on the colorbar.

So yes, I could explicitly link the basemap to the first Axes myself. I still think my suggestion would be far less confusing, but I won't lose sleep over it. In any case, I think the snippet I put in the latest message could simplify the code (just drop the line setting self.ax to ax)...

Pierre: Doing what you suggest (having Basemap.__init__ automatically set self.ax to the current axes) will break pickling, so I can't do that. I think the next best thing is just to set it manually. I know the colorbar behavior is annoying, but I think it's just something you have to live with if you use the pylab interface.

-Jeff

···

On Jun 23, 2009, at 8:27 AM, Jeff Whitaker wrote:

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

Oh, I'm sorry for the misunderstanding: I never suggested that Basemap.ax should be set at creation (apart from Basemap.ax=None). Instead, I suggested that it would be set when a drawing method is called that requires access to the underlying Axes (basically, all the plotting methods).
That way, as soon as something is plotted, we associate the basemap instance with one particular Axes instance and we stick to it by default. We can always break the link by changing basemap.ax (that is, associate to another Axes instance), but we don't have the surprise of using the last Axes instance by default.

Now, the more I think about it, the more I'd prefer to separate Basemaps from Axes. Right now, self.ax assures the connection in a way I find frustrating. I'd prefer getting rid of Basemap.ax and force 'ax' to be defined all the time.

Alternatively, we could consider having 2 separate objects: a Basemap that stores all the projection information but has *NO* plotting methods, and a MapAxes that inherits from Axes and requires a specific Basemap attribute at creation. The current plotting routines would be associated with the MapAxes object.

···

On Jun 23, 2009, at 6:01 PM, Jeff Whitaker wrote:

Pierre: Doing what you suggest (having Basemap.__init__ automatically set self.ax to the current axes) will break pickling, so I can't do that.

Pierre GM wrote:

  

Pierre: Doing what you suggest (having Basemap.__init__ automatically set self.ax to the current axes) will break pickling, so I can't do that.
    
Oh, I'm sorry for the misunderstanding: I never suggested that Basemap.ax should be set at creation (apart from Basemap.ax=None). Instead, I suggested that it would be set when a drawing method is called that requires access to the underlying Axes (basically, all the plotting methods).
That way, as soon as something is plotted, we associate the basemap instance with one particular Axes instance and we stick to it by default. We can always break the link by changing basemap.ax (that is, associate to another Axes instance), but we don't have the surprise of using the last Axes instance by default.
  
OK, Pierre. Now I understand. That sounds reasonable, and I don't think it will break any existing code.
Now, the more I think about it, the more I'd prefer to separate Basemaps from Axes. Right now, self.ax assures the connection in a way I find frustrating. I'd prefer getting rid of Basemap.ax and force 'ax' to be defined all the time.
  
Don't exactly know what you mean here - make the ax keyword to the drawing methods mandatory?
Alternatively, we could consider having 2 separate objects: a Basemap that stores all the projection information but has *NO* plotting methods, and a MapAxes that inherits from Axes and requires a specific Basemap attribute at creation. The current plotting routines would be associated with the MapAxes object.
  
Hmm. I see how this could work, but what would be the added benefit (beyond what we would get by implementing your first suggestion)?

-Jeff

···

On Jun 23, 2009, at 6:01 PM, Jeff Whitaker wrote: