Skip to content

Possibility to provide default map background/ elements to plot #880

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
cwerner opened this issue Jun 11, 2016 · 2 comments
Closed

Possibility to provide default map background/ elements to plot #880

cwerner opened this issue Jun 11, 2016 · 2 comments
Labels

Comments

@cwerner
Copy link

cwerner commented Jun 11, 2016

Hi.

Really enjoying xarray! Converting all my scripts and on the quest to simplify my plotting.

For my current project I need loads of maps and generally add a land/ ocean layer and country boundaries as well as an default extent to the plot axes...

I use for instance a extra layer like this:

import cartopy.crs as cars
import cartopy.feature as feature

# default map backgrounds    
countries = cfeature.NaturalEarthFeature(
    category='cultural',
    name='admin_0_countries',
    scale='50m',
    facecolor='none')

An example from a class I work on right now:


    def plot_monthly(self, figsize=(12,10)):
        _unit = 'n.d.'
        _name = 'var' 
        if 'units' in self._dataArray.attrs.keys():
            _unit = self._dataArray.attrs['units']


        self._fig, self._axes = plt.subplots(ncols=4, nrows=3, \
                                             figsize=figsize, subplot_kw={'projection': ccrs.PlateCarree()})

        _min = self._dataArray.min()
        _max = self._dataArray.max()

        print self._dataArray

        for i, ax in enumerate(self._axes.flatten()):
            ax.set_extent( self._extent )
            ax.add_feature(self._countries, edgecolor='gray')     
            ax.add_feature(self._ocean)                           
            ax.coastlines(resolution='50m')
            ax.set_title(self._monthNames[i+1])
            _plot = xr.plot.plot(self._dataArray.sel(month=i+1), ax=ax, \
                            vmin=_min, vmax=_max, \
                            transform=ccrs.PlateCarree(), \
                            add_labels=False,
                            robust=True, add_colorbar=False)


        self._fig.subplots_adjust(right=0.8)
        _cbar_ax = self._fig.add_axes([0.85, 0.15, 0.05, 0.7])

        _var_str = "%s [%s]" % (_name, _unit)
        self._fig.colorbar(_plot, cax=_cbar_ax, label=_var_str)

This is a bit clumsy at the moment - I basically define the axes for each subplot (say 1..12 month), loop over them, select the axis and add them with ax.set_extent(), ax.add_feature() etc...

This works, but I'd rather use the plot function within DataArray or DataSet... Also thinking about using FacetGrid instead of doing it manually.

I thought about using the new decorators to patch this onto a custom plot directive but my Python is not really advanced enough for decorators and the inner functioning of array it seems...

@xr.register_dataarray_accessor('map')
class MapDecorator(object):
    def __init__(self, xarray_obj):
        self._obj = xarray_obj

    def plot(self, **kwargs):
        """Plot data on a map."""

        print "my decorator"

        #ax.set_extent([102, 110, 8, 24])
        ## add map elements
        #ax.add_feature(countries, edgecolor='gray')     # country borders
        #ax.add_feature(ocean)                           # ocean
        #ax.coastlines(resolution='50m')                 # coastlines

        p = self._obj.plot( kwargs )
        return p

Not sure if this is a valid path or how one would do that? I would also like to have some default arguments (projection=)

Cheers,
Christian

@mathause
Copy link
Collaborator

I wrote a function that I call geocolormesh which automatically creates cartopy GeoAxes for single plots and for FacetGrids. This may go in the direction of what you would like to get. I find this very convenient for fast plotting - once I do the final plots some more work is needed. Unfortunately this is not possible without some changes* in the default plotting function (and also in facet grid). Thus, I added a pull request. Not sure what the developers will think of this.

*Because it is not possible to change the projection of axes once they are created.

@stale
Copy link

stale bot commented Jan 27, 2019

In order to maintain a list of currently relevant issues, we mark issues as stale after a period of inactivity
If this issue remains relevant, please comment here; otherwise it will be marked as closed automatically

@stale stale bot added the stale label Jan 27, 2019
@stale stale bot closed this as completed Feb 26, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants