예제 #1
0
def test_save_func(tmpdir):
    plot.save_func(str(tmpdir) + 'test.png', False)
예제 #2
0
파일: mcwd.py 프로젝트: Maduvi/obrero
def panel_plot_malhi(table_data,
                     wmm=180,
                     hmm=120,
                     names=['CTL', 'EXP'],
                     save=None,
                     transparent=False):
    """Panels version of `plot_malhi`. 

    Here we separate several regions we have defined in COORD_REGION2
    within the plasim_t21.py module.

        REGION  LOCATION
        ----------------------------------------------
        R1: North America
        R2: Central America and Northern South America
        R3: Central South America (Amazonia)
        R4: Eurasia
        R5: East Africa
        R6: Australia

    Parameters
    ----------
    See `plot_malhi` parameters.

    Returns
    -------
    matplotlib.figure.Figure object with panel plots.
    """  # noqa

    # settings
    oplot.plot_settings()

    # check if df or text file
    if isinstance(table_data, str):
        table = pd.read_csv(table_data, index_col=0)
    elif isinstance(table_data, pd.core.frame.DataFrame):
        table = table_data

    # check it was the output from composite_map
    colnames = [
        'lon', 'lat', 'ctl_map', 'exp_map', 'ctl_mcwd', 'exp_mcwd', 'comp'
    ]
    for x in colnames:
        if x in table.columns:
            pass
        else:
            msg = 'table missing \'' + x + '\' column'
            raise ValueError(msg)

    nrows = table.index.size

    # colors dictionary
    cmap_base = matplotlib.cm.get_cmap('BrBG')
    cmap = [cmap_base(x) for x in [0., 0.2, 0.28, 0.38, 0.8, 1.]]
    cnorm = oplot.BoundaryNorm(range(7), ncolors=6, clip=True)
    cdict = {
        '0.5': cmap[0],
        '1.5': cmap[1],
        '2.5': cmap[2],
        '3.5': cmap[3],
        '4.5': cmap[4],
        '5.5': cmap[5]
    }

    # create figure
    fig = oplot.plt.figure(figsize=(wmm / 25.4, hmm / 25.4))

    # create axes for continents
    axes = fig.subplots(2, 3, sharey=True)

    # to guess xlim later
    xp1, xp2, xp3, xp4, xp5, xp6 = [], [], [], [], [], []

    for i in range(nrows):
        row = table.loc[i]
        lat = row.lat
        lon = row.lon

        # get marker based on region
        key = '(%8.5f, %g)' % (lat, lon)
        reg = COORD_REGION2[key]
        mark = REG_MARK2[reg]

        x = [row.ctl_mcwd, row.exp_mcwd]
        y = [row.ctl_map, row.exp_map]
        c = cdict[str(row.comp)]

        if reg == 'R1':
            axes[0, 0].plot(x, y, color=c, linewidth=1, alpha=0.5)
            axes[0, 0].plot(x[1], y[1], mark, color=c, ms=2)
            xp1.extend(x)
        elif reg == 'R2':
            axes[0, 1].plot(x, y, color=c, linewidth=1, alpha=0.5)
            axes[0, 1].plot(x[1], y[1], mark, color=c, ms=2)
            xp2.extend(x)
        elif reg == 'R3':
            axes[0, 2].plot(x, y, color=c, linewidth=1, alpha=0.5)
            axes[0, 2].plot(x[1], y[1], mark, color=c, ms=2)
            xp3.extend(x)
        elif reg == 'R4':
            axes[1, 0].plot(x, y, color=c, linewidth=1, alpha=0.5)
            axes[1, 0].plot(x[1], y[1], mark, color=c, ms=2)
            xp4.extend(x)
        elif reg == 'R5':
            axes[1, 1].plot(x, y, color=c, linewidth=1, alpha=0.5)
            axes[1, 1].plot(x[1], y[1], mark, color=c, ms=2)
            xp5.extend(x)
        elif reg == 'R6':
            axes[1, 2].plot(x, y, color=c, linewidth=1, alpha=0.5)
            axes[1, 2].plot(x[1], y[1], mark, color=c, ms=2)
            xp6.extend(x)
        else:
            pass

    # plot settings
    for ax in axes[1, :]:
        ax.set_xlabel('MCWD (mm)')

    for ax in axes[:, 0]:
        ax.set_ylabel(oplot.replace_minus('MAP (mm year$^{-1}$)'))

    # ylim and change hyphen
    for ax in axes.flatten():
        ax.set_ylim([0, 3500])
        ax.xaxis.set_major_formatter(oplot.FuncFormatter(oplot.no_hyphen))

    # fix xlim
    for (x, ax) in zip([xp1, xp2, xp3, xp4, xp5, xp6], axes.flatten()):
        positive_minx = abs(min(x))
        positive_minx -= positive_minx % -100
        xlim = [-positive_minx, 0]
        ax.set_xlim(xlim)

    # titles
    axes[0, 0].set_title('(a) North America')
    axes[0, 1].set_title('(b) Central America/Northern South America')
    axes[0, 2].set_title('(c) Central South America')
    axes[1, 0].set_title('(d) Eurasia')
    axes[1, 1].set_title('(e) South East Africa')
    axes[1, 2].set_title('(f) Australia')

    # legend
    custom_names = ['Distance to ' + names[0], names[1]]
    custom_lines = [
        Line2D([0], [0], color='black', lw=1, alpha=0.5),
        Line2D([0], [0], linestyle='', marker='^', color='black', ms=2)
    ]
    axes[0, 0].legend(custom_lines, custom_names, loc=2, fontsize=6)
    axes[0, 1].legend(custom_lines, custom_names, loc=4, fontsize=6)
    axes[0, 2].legend(custom_lines, custom_names, loc=4, fontsize=6)
    axes[1, 0].legend(custom_lines, custom_names, loc=3, fontsize=6)
    axes[1, 1].legend(custom_lines, custom_names, loc=2, fontsize=6)
    axes[1, 2].legend(custom_lines, custom_names, loc=2, fontsize=6)

    # maximize
    oplot.plt.tight_layout()

    # save if given filename
    oplot.save_func(save, transparent)

    return fig
예제 #3
0
파일: mcwd.py 프로젝트: Maduvi/obrero
def plot_mcwd_composite(composite,
                        wmm=100,
                        hmm=80,
                        axes=None,
                        proj=None,
                        lon0=0,
                        save=None,
                        transparent=False):
    """Plot results from `mcwd_composite_map`.

    This is a custom map that combines significant differences in both
    mean annual precipitation (MAP) and maximum climatological water
    deficit (MCWD). To do this we first find significant
    differences. Then we ask whether this significan differences are
    above 10% of a control value. Based on this, each grid cell is
    assigned either numpy.nan or a value. Here we define how to plot
    those values in such composite map.

    Parameters
    ----------
    composite: xarray.DataArray
        This must be the output of function `mcwd_composite_map`.
    wmm: float, optional
        Width of the figure to plot in units of mm. Default is 100 mm.
    hmm: float, optional
        Height of the figure to plot in units of mm. Default is 80 mm.
    axes: cartopy.mpl.geoaxes.GeoAxes, optional
        This axes should have some projection from Cartopy. If it is
        not provided, brand new axes will be created with default
        projection `proj`.
    proj: cartopy.crs.Projection, optional
        Map projection to be used to create the axes if not
        provided. By default we use the Mollweide projection.
    lon0: float, optional
        Central longitude to create the projection in the axes. By
        default the central longitudes is the Greenwich meridian. This
        argument is only meaningfull for the default projection which 
        is Mollweide. Otherwise it is unused.
    save: bool or str, optional
        This can be a boolean flag to create a PDF file with the
        plotted map, in which case the file will be named
        `output.pdf`, or a string with a specific name for the file.
        Default is only show the plot.
    transparent: bool, optional
        If `save` is True or some str object with a name, this keyword
        controls how the background is plotted. If True, then
        background will be transparent. This is useful if the image is
        to be used in slideshows. Default is False.

    Returns
    -------
    matplotlib.axes.Axes with plot attached.    
    """  # noqa

    # plot settings
    oplot.plot_settings()

    # get cyclic values and coords
    cval, clon = oplot.get_cyclic_values(composite)
    lat = composite.latitude.values

    # get projection if none given
    if proj is None:
        proj = oplot.moll(central_longitude=lon0)

        # in case we plot a single plot
    if axes is None:
        oplot.plt.figure(figsize=(wmm / 25.4, hmm / 25.4))
        axes = oplot.plt.axes(projection=proj)
        maximize = 1
    else:
        maximize = 0

    # colormap
    # cmap = oplot.ListedColormap(['FireBrick', 'Chocolate', 'Orange',
    #                              'Yellow', 'YellowGreen', 'DarkGreen'])
    cmap_base = matplotlib.cm.get_cmap('BrBG')
    cmap = oplot.ListedColormap(
        [cmap_base(x) for x in [0., 0.2, 0.28, 0.38, 0.8, 1.]])

    # levels
    lev = range(7)

    # normalize to number of colors
    cnorm = oplot.BoundaryNorm(lev, ncolors=cmap.N, clip=True)

    # add shorelines
    axes.coastlines(resolution='110m')

    # set global
    axes.set_global()

    # add gridlines
    oplot.add_gridlines(axes)

    # fix coords
    corlon, corlat = oplot.corner_coords(clon, lat)

    # plot map
    fmap = axes.pcolor(corlon,
                       corlat,
                       cval,
                       cmap=cmap,
                       norm=cnorm,
                       transform=oplot.pcar())

    # add colorbar
    cb = oplot.plt.colorbar(fmap,
                            orientation='horizontal',
                            pad=0.15,
                            shrink=0.8,
                            ax=axes,
                            extend='both')

    # colorbar ticks and labels
    fsize = 7
    bottom = [
        'much\ngreater', 'greater', 'much\ngreater', 'greater', 'less',
        'much\nless'
    ]
    top = [
        'much\nless', 'much\nless', 'less', 'less', 'greater', 'much\ngreater'
    ]
    cb.set_ticks(np.arange(0.5, 6.5, 1))
    cb.ax.tick_params(top=True)
    cb.ax.set_xticklabels(bottom, multialignment='center', fontsize=fsize)

    # add top ticklabels with custom text
    tickpos = cb.ax.get_xticks()
    for i, x in enumerate(tickpos):
        cb.ax.text(x,
                   1.8,
                   top[i],
                   fontsize=fsize,
                   ha='center',
                   multialignment='center')

    # add titles at top and bottom
    cb.ax.text(-0.05,
               2,
               r' \textbf{MAP}',
               fontsize=fsize,
               ha='center',
               va='bottom')
    cb.ax.text(-0.07,
               -2,
               r'\textbf{MCWD}',
               fontsize=fsize,
               ha='center',
               va='bottom')

    # maximize if only one
    if maximize == 1:
        oplot.plt.tight_layout()

        # savefig if provided name
        oplot.save_func(save, transparent)

    return axes
예제 #4
0
파일: mcwd.py 프로젝트: Maduvi/obrero
def plot_malhi(table_data,
               wmm=90,
               hmm=90,
               names=['CTL', 'EXP'],
               axes=None,
               ylim=[0, 4000],
               title='',
               bounds=None,
               legend=True,
               ylabel=r'MAP (mm year$^{-1}$)',
               xlabel=r'MCWD (mm)',
               save=None,
               transparent=False):
    """Plot output CSV file from `mcwd_composite_map`.

    This function will plot the table in comma separated values (CSV)
    format that the function `mcwd_composite_map` creates. It will
    read it as a dataframe and plot it, or you can go ahead and give the
    data frame directly. Since `mcwd_composite_map` only considers 2
    experiments, one control and one experimental simulation, this
    plot will do the same.
    
    Parameters
    ----------
    table_data: str or pandas.DataFrame
        If this is a string, it must be the name of the CSV file that
        `mcwd_composite_map` creates. But it can also be the
        pandas.DataFrame directly, without need of creating file.
    wmm: float, optional
        Width of the figure to plot in units of mm. Default is 90 mm.
    hmm: float, optional
        Height of the figure to plot in units of mm. Default is 90 mm.
    names: list
        List with only 2 str names for two experiments. One of them is
        usually control. Default is ['CTL', 'EXP'].
    axes: matplotlib.axes.Axes, optional
        If this is going to be part of another bigger figure, a
        subplot axes can be provided for this plot to attach the ONI
        plot.
    ylim: list, optional
        List object with two float values to define the limits in the
        y axis. Default is [0, 4000].
    title: str, optional
        Center top title if desired. Default is empty.
    bounds: tuple or list, optional
        Bounds must have the sequence: [x0, x1, y0, y1], using x for
        longitudes and y for latitudes. Default is None.
    legend: bool, optional
        Whether to show legend or not.
    xlabel: str, optional
        Title for the x axis. Default is 'MCWD (mm)'.
    ylabel: str, optional
        Title for the y axis. Default is 'MAP (mm year-1)'.
    save: bool or str, optional
        This can be a boolean flag to create a PDF file with the
        plotted map, in which case the file will be named
        `output.pdf`, or a string with a specific name for the file.
        Default is only show the plot.
    transparent: bool, optional
        If `save` is True or some str object with a name, this keyword
        controls how the background is plotted. If True, then
        background will be transparent. This is useful if the image is
        to be used in slideshows. Default is False.

    Returns
    -------
    matplotlib.axes.Axes with plot attached.    
    """  # noqa

    # plot settings
    oplot.plot_settings()

    # check if df or text file
    if isinstance(table_data, str):
        table = pd.read_csv(table_data, index_col=0)
    elif isinstance(table_data, pd.core.frame.DataFrame):
        table = table_data

    # check it was the output from composite_map
    colnames = [
        'lon', 'lat', 'ctl_map', 'exp_map', 'ctl_mcwd', 'exp_mcwd', 'comp'
    ]
    for x in colnames:
        if x in table.columns:
            pass
        else:
            msg = 'table missing \'' + x + '\' column'
            raise ValueError(msg)

    nrows = table.index.size

    # in case we plot a single plot
    if axes is None:
        oplot.plt.figure(figsize=(wmm / 25.4, hmm / 25.4))
        axes = oplot.plt.axes()
        maximize = 1
    else:
        maximize = 0

    # colors dictionary
    cmap_base = matplotlib.cm.get_cmap('BrBG')
    cmap = [cmap_base(x) for x in [0., 0.2, 0.28, 0.38, 0.8, 1.]]
    cdict = {
        '0.5': cmap[0],
        '1.5': cmap[1],
        '2.5': cmap[2],
        '3.5': cmap[3],
        '4.5': cmap[4],
        '5.5': cmap[5]
    }

    # custom legend lines
    regions = []
    markers = []
    custom_names = ['Distance to ' + names[0]]
    custom_lines = [Line2D([0], [0], color='black', lw=0.5, alpha=0.5)]

    # to guess xlim later
    xplotted = []

    for i in range(nrows):
        row = table.loc[i]
        lat = row.lat
        lon = row.lon

        # get marker based on region
        key = '(%8.5f, %g)' % (lat, lon)
        reg = COORD_REGION1[key]
        mark = REG_MARK1[reg]

        if reg not in regions:
            regions.append(reg)

        if mark not in markers:
            markers.append(mark)

        # fix lon to be -180 - 180
        if lon > 180:
            lon = lon - 360

        x = [row.ctl_mcwd, row.exp_mcwd]
        y = [row.ctl_map, row.exp_map]
        c = cdict[str(row.comp)]

        if bounds is not None:

            # check bounds
            utils.check_bounds(bounds)

            # unpack bounds
            x0, x1, y0, y1 = bounds

            if (lon > x0) and (lon <= x1):
                if (lat > y0) and (lat <= y1):
                    axes.plot(x, y, color=c)
                    axes.plot(row.exp_mcwd, row.exp_map, '^', color=c)

                    xplotted.extend(x)
        else:
            axes.plot(x, y, color=c, linewidth=0.5, alpha=0.5)
            axes.plot(row.exp_mcwd, row.exp_map, mark, color=c, ms=2)
            xplotted.extend(x)

    # guess min xlim
    if xplotted != []:
        positive_minx = abs(min(xplotted))
        positive_minx -= positive_minx % -100
        xlim = [-positive_minx, 0]
        axes.set_xlim(xlim)

    # plot settings
    axes.set_xlabel(xlabel)
    axes.set_ylabel(oplot.replace_minus(ylabel))
    axes.set_ylim(ylim)
    axes.set_title(title)
    axes.xaxis.set_major_formatter(oplot.FuncFormatter(oplot.no_hyphen))

    if legend is True:

        for r in regions:
            custom_names.append(r)

        for m in markers:
            custom_lines.append(
                Line2D([0], [0], linestyle='', marker=m, color='black', ms=2))
        axes.legend(custom_lines, custom_names, loc=2, ncol=3, fontsize=6)

    # maximize plot if only one
    if maximize == 1:
        oplot.plt.tight_layout()

        # savefig if provided name
        oplot.save_func(save, transparent)

    return axes
예제 #5
0
파일: mcwd.py 프로젝트: Maduvi/obrero
def plot_regions(composite,
                 bnds,
                 regname,
                 xloc,
                 yloc,
                 wmm=30,
                 hmm=30,
                 axes=None,
                 proj=None,
                 lon0=0,
                 save=None,
                 transparent=False):

    # plot settings
    oplot.plot_settings()

    # copy data
    compcopy = composite.copy()

    # select region
    x0, x1, y0, y1 = bnds
    reg = compcopy.sel(latitude=slice(y0, y1), longitude=slice(x0, x1))

    # get coords
    lon = reg.longitude.values
    lat = reg.latitude.values

    # shape
    nlat, mlon = reg.shape

    for i in range(nlat):
        ii = lat[i]
        for j in range(mlon):
            jj = lon[j]

            # get marker based on region
            key = '(%8.5f, %g)' % (ii, jj)

            try:
                region = COORD_REGION2[key]
            except:
                region = 'OTHER'

            if region != regname:
                reg.values[i, j] = np.nan

    # get projection if none given
    if proj is None:
        proj = oplot.pcar(central_longitude=lon0)

        # in case we plot a single plot
    if axes is None:
        oplot.plt.figure(figsize=(wmm / 25.4, hmm / 25.4))
        axes = oplot.plt.axes(projection=proj)
        maximize = 1
    else:
        maximize = 0

    # colormap
    cmap_base = matplotlib.cm.get_cmap('BrBG')
    cmap = oplot.ListedColormap(
        [cmap_base(x) for x in [0., 0.2, 0.28, 0.38, 0.8, 1.]])

    # levels
    lev = range(7)

    # normalize to number of colors
    cnorm = oplot.BoundaryNorm(lev, ncolors=cmap.N, clip=True)

    # add shorelines
    axes.coastlines(resolution='110m')

    # set global
    axes.set_extent(bnds)

    # add gridlines
    oplot.pcar_gridliner(axes, bnds, xloc, yloc)

    # fix coords
    corlon, corlat = oplot.corner_coords(lon, lat)

    # plot map
    fmap = axes.pcolor(corlon,
                       corlat,
                       reg.values,
                       cmap=cmap,
                       norm=cnorm,
                       transform=oplot.pcar())

    # maximize if only one
    if maximize == 1:
        oplot.plt.tight_layout()

        # savefig if provided name
        oplot.save_func(save, transparent)

    return axes