예제 #1
0
def run_all_plots():

    #***********************
    # MODIS - centre

    cubelist = iris.load(
        os.path.join(data_loc,
                     "MODIS.CMG.{}.SOS.EOS.Anomaly.nc".format(settings.YEAR)))

    for c, cube in enumerate(cubelist):
        if cube.name() == "SOS":
            sos_cube = cubelist[c]

    # deal with NANS
    sos_cube.data = np.ma.masked_where(sos_cube.data != sos_cube.data,
                                       sos_cube.data)

    # read in sites

    us_locations = read_us_phenocam(os.path.join(data_loc,
                                                 "phenocam_locs.txt"))

    fig = plt.figure(figsize=(8, 12))
    plt.clf()

    # set up plot settings
    BOUNDS = [-100, -20, -10, -5, -2, 0, 2, 5, 10, 20, 100]

    LABELS = "(c) Start of Season (SOS)"  #, "(b) End of Season (EOS)"]

    # boundary circle
    theta = np.linspace(0, 2 * np.pi, 100)
    center, radius = [0.5, 0.5], 0.5
    verts = np.vstack([np.sin(theta), np.cos(theta)]).T
    circle = mpath.Path(verts * radius + center)

    # axes for polar plot
    ax = plt.axes(
        [0.05, 0.01, 0.9, 0.65],
        projection=cartopy.crs.NorthPolarStereo(central_longitude=300.0))

    plot_cube = sos_cube

    if settings.OUTFMT in [".eps", ".pdf"]:
        if plot_cube.coord("latitude").points.shape[0] > 90 or plot_cube.coord(
                "longitude").points.shape[0] > 360:
            regrid_size = 1.0
            print(
                "Regridding cube for {} output to {} degree resolution".format(
                    settings.OUTFMT, regrid_size))
            print("Old Shape {}".format(plot_cube.data.shape))
            plot_cube = utils.regrid_cube(plot_cube, regrid_size, regrid_size)
            print("New Shape {}".format(plot_cube.data.shape))

    ax.gridlines()  #draw_labels=True)
    ax.add_feature(cartopy.feature.LAND,
                   zorder=0,
                   facecolor="0.9",
                   edgecolor="k")
    ax.coastlines()
    ax.set_boundary(circle, transform=ax.transAxes)

    cmap = settings.COLOURMAP_DICT["phenological_r"]
    norm = mpl.cm.colors.BoundaryNorm(BOUNDS, cmap.N)
    mesh = iris.plot.pcolormesh(plot_cube, cmap=cmap, norm=norm, axes=ax)

    # plot scatter
    COL = "yellow"
    ax.scatter(us_locations[1],
               us_locations[0],
               c=COL,
               s=100,
               edgecolor="k",
               transform=cartopy.crs.Geodetic(),
               zorder=10)
    ax.scatter(-2.9376,
               54.3739,
               c=COL,
               s=100,
               edgecolor="k",
               transform=cartopy.crs.Geodetic(),
               zorder=10)

    # uk box
    region = [-10.0, 49.0, 3.0, 60.0]
    ax.plot([region[0], region[0]], [region[1], region[3]],
            c=COL,
            ls='-',
            lw=4,
            zorder=10,
            transform=cartopy.crs.PlateCarree())
    ax.plot([region[2], region[2]], [region[1], region[3]],
            c=COL,
            ls='-',
            lw=4,
            zorder=10,
            transform=cartopy.crs.PlateCarree())
    ax.plot([region[0], region[2]], [region[1], region[1]],
            c=COL,
            ls='-',
            lw=4,
            zorder=10,
            transform=cartopy.crs.Geodetic())
    ax.plot([region[0], region[2]], [region[3], region[3]],
            c=COL,
            ls='-',
            lw=4,
            zorder=10,
            transform=cartopy.crs.Geodetic())

    COL = "k"
    ax.plot([region[0], region[0]], [region[1], region[3]],
            c=COL,
            ls='-',
            lw=5,
            zorder=9,
            transform=cartopy.crs.PlateCarree())
    ax.plot([region[2], region[2]], [region[1], region[3]],
            c=COL,
            ls='-',
            lw=5,
            zorder=9,
            transform=cartopy.crs.PlateCarree())
    ax.plot([region[0], region[2]], [region[1], region[1]],
            c=COL,
            ls='-',
            lw=5,
            zorder=9,
            transform=cartopy.crs.Geodetic())
    ax.plot([region[0], region[2]], [region[3], region[3]],
            c=COL,
            ls='-',
            lw=5,
            zorder=9,
            transform=cartopy.crs.Geodetic())

    # label axes
    ax.text(-0.1,
            1.0,
            LABELS,
            fontsize=settings.FONTSIZE * 0.8,
            transform=ax.transAxes)

    cb = plt.colorbar(mesh,
                      orientation='horizontal',
                      ticks=BOUNDS[1:-1],
                      label="Anomaly (days)",
                      drawedges=True,
                      fraction=0.1,
                      pad=0.05,
                      aspect=15,
                      shrink=0.8)
    # prettify
    cb.set_ticklabels(["{:g}".format(b) for b in BOUNDS[1:-1]])
    cb.outline.set_linewidth(2)
    cb.dividers.set_color('k')
    cb.dividers.set_linewidth(2)

    ax.set_extent([-180, 180, 30, 90], cartopy.crs.PlateCarree())

    for lat in range(30, 100, 10):
        ax.text(180,
                lat,
                '{}$^\circ$N'.format(lat),
                transform=cartopy.crs.Geodetic())

    fig.subplots_adjust(bottom=0.05,
                        top=0.95,
                        left=0.04,
                        right=0.95,
                        wspace=0.02)

    del sos_cube
    del cubelist

    #***********************
    # MODIS timeseries - 2018

    sos_na, sos_ea, sprt_na_orig, sprt_ea_orig = read_modis_ts(
        os.path.join(
            data_loc,
            "MODIS.CMG.{}.SOS.EOS.SPRT.FALT.TS.csv".format(settings.YEAR)))

    dummy, sos_na = utils.calculate_climatology_and_anomalies_1d(
        sos_na, 2000, 2010)
    dummy, sos_ea = utils.calculate_climatology_and_anomalies_1d(
        sos_ea, 2000, 2010)

    dummy, sprt_na = utils.calculate_climatology_and_anomalies_1d(
        sprt_na_orig, 2000, 2010)
    dummy, sprt_ea = utils.calculate_climatology_and_anomalies_1d(
        sprt_ea_orig, 2000, 2010)

    ax = plt.axes([0.1, 0.7, 0.8, 0.15])
    label = "(b) North America"
    anomalies = [
        "2018 SOS Anomaly = 1.86 days",
        "2018 Spring T anomaly = -0.75 " + r'$^{\circ}$' + "C"
    ]

    plot_modis_ts(ax, sos_na, sprt_na, sprt_na_orig, label, anomalies,
                  LEGEND_LOC)

    na_trend = -0.64 / 10
    ax.plot([sos_na.times[0], sos_na.times[-1]],
            utils.trendline(na_trend, sos_na.times),
            ls="--",
            zorder=10,
            c="g",
            lw=2)
    print(utils.trendline(na_trend, sos_na.times))

    ax1 = plt.axes([0.1, 0.85, 0.8, 0.15], sharex=ax)
    label = "(a) Eurasia"
    anomalies = [
        "2018 SOS Anomaly = 2.01 days",
        "2018 Spring T anomaly = 0.13 " + r'$^{\circ}$' + "C"
    ]

    plot_modis_ts(ax1, sos_ea, sprt_ea, sprt_ea_orig, label, anomalies, "")

    ea_trend = -1.59 / 10
    ax1.plot([sos_ea.times[0], sos_ea.times[-1]],
             utils.trendline(ea_trend, sos_ea.times),
             ls="--",
             zorder=10,
             c="g",
             lw=2)
    print(utils.trendline(ea_trend, sos_ea.times))

    plt.setp(ax1.get_xticklabels(), visible=False)
    plt.setp(ax.get_xticklabels(), visible=True)

    fig.text(0.05, 0.92, "SOS Anomaly (days)", rotation="vertical")
    fig.text(0.95,
             0.92,
             "Temperature Anomaly (" + r'$^{\circ}$' + "C)",
             rotation="vertical")

    plt.savefig(image_loc +
                "PHEN_modis_{}{}".format(settings.YEAR, settings.OUTFMT))

    #***********************
    # US timeseries - 2018

    fig = plt.figure(figsize=(8, 10))
    plt.clf()

    barrow, ozarks, turkey = read_us_phenocam_csv(
        os.path.join(data_loc, "Richardson PhenoCam plots for Sidebar.csv"))

    ax = plt.axes([0.1, 0.03, 0.35, 0.17])
    plot_us_phenocam(ax, barrow, [160, 229], "Barrow")
    ax.text(0.05, 0.85, "(e) Barrow", transform=ax.transAxes)
    ax = plt.axes([0.1, 0.23, 0.35, 0.17])
    plot_us_phenocam(ax,
                     ozarks, [90, 159],
                     "Ozarks",
                     ylabel="Vegetation Greenness Index",
                     legend=True)
    ax.text(0.05, 0.85, "(d) Ozarks", transform=ax.transAxes)
    ax = plt.axes([0.1, 0.43, 0.35, 0.17])
    plot_us_phenocam(ax, turkey, [60, 129], "Turkey Point")
    ax.text(0.05, 0.85, "(c) Turkey Point", transform=ax.transAxes)

    ax = plt.axes([0.48, 0.02, 0.25, 0.2])
    plot_images(ax, "barrow_2017_06_27_100002.jpg")
    ax = plt.axes([0.48, 0.22, 0.25, 0.2])
    plot_images(ax, "missouriozarks_2017_04_30_163113.jpg")
    ax = plt.axes([0.48, 0.42, 0.25, 0.2])
    plot_images(ax, "turkeypointenf39_2017_04_18_113106.jpg")

    ax = plt.axes([0.73, 0.02, 0.25, 0.2])
    plot_images(ax, "barrow_2018_06_27_103003.jpg")
    ax = plt.axes([0.73, 0.22, 0.25, 0.2])
    plot_images(ax, "missouriozarks_2018_04_30_163113.jpg")
    ax = plt.axes([0.73, 0.42, 0.25, 0.2])
    plot_images(ax, "turkeypointenf39_2018_04_18_113302.jpg")

    plt.figtext(0.6, 0.02, "2017")
    plt.figtext(0.85, 0.02, "2018")

    #***********************
    # UK timeseries - 2018

    ax = plt.axes([0.1, 0.65, 0.85, 0.15])

    oak = read_uk_oak_csv(
        os.path.join(data_loc, "UK Oak budburst 2000-2018.csv"))
    utils.plot_ts_panel(ax, [oak], "-", "phenological", loc="lower left")
    ax.set_ylim([94, 124])
    ax.text(0.03, 0.8, "(b) Oak Budburst", transform=ax.transAxes)
    # fix the legend label to be italic
    handles, labels = ax.get_legend_handles_labels()
    labels[
        0] = "$\mathregular{\mathit{Quercus}}$" + " " + "$\mathregular{\mathit{robur}}$"
    ax.legend(handles, labels, frameon=False, loc="lower left")

    # need legend once have other panel's data
    north, south = read_windermere_csv(
        os.path.join(data_loc, "Windermere_2000-2018.csv"))
    ax2 = plt.axes([0.1, 0.8, 0.85, 0.15], sharex=ax)
    utils.plot_ts_panel(ax2, [north, south],
                        "-",
                        "phenological",
                        loc="lower right")
    ax2.set_ylim([79, 159])
    plt.setp(ax2.get_xticklabels(), visible=False)
    ax2.text(0.03, 0.8, "(a) Windermere", transform=ax2.transAxes)

    ax2.set_xlim([1998, 2020])
    ax.set_xlim([1998, 2020])

    fig.text(0.03, 0.835, "Day of year", rotation="vertical")

    plt.savefig(image_loc +
                "PHEN_timeseries_{}{}".format(settings.YEAR, settings.OUTFMT))
    plt.close()

    return  # run_all_plots
예제 #2
0
def run_all_plots():

    #************************************************************************
    # Timeseries plot
    if True:

        monthly = read_data(DATALOC + "monthlist", "AOD monthly")
        annual = read_data(DATALOC + "yearlist", "AOD annual")

        minor_tick_interval = 1
        minorLocator = MultipleLocator(minor_tick_interval)
        COLOURS = settings.COLOURS["composition"]

        fig = plt.figure(figsize=(8, 5))
        ax = plt.axes([0.13, 0.07, 0.85, 0.86])

        plt.plot(monthly.times,
                 monthly.data,
                 COLOURS[monthly.name],
                 ls='-',
                 label=monthly.name,
                 lw=LW)
        plt.plot(annual.times,
                 annual.data,
                 COLOURS[annual.name],
                 ls='-',
                 label=annual.name,
                 lw=LW)

        ax.legend(loc=LEGEND_LOC,
                  ncol=1,
                  frameon=False,
                  prop={'size': settings.LEGEND_FONTSIZE},
                  labelspacing=0.1,
                  columnspacing=0.5)

        # prettify
        ax.xaxis.set_minor_locator(minorLocator)
        utils.thicken_panel_border(ax)

        fig.text(0.03,
                 0.5,
                 "AOD",
                 va='center',
                 rotation='vertical',
                 fontsize=settings.FONTSIZE)

        plt.xlim([2002.5, int(settings.YEAR) + 1.5])
        plt.ylim([0.09, 0.21])
        for tick in ax.yaxis.get_major_ticks():
            tick.label.set_fontsize(settings.FONTSIZE)
        for tick in ax.xaxis.get_major_ticks():
            tick.label.set_fontsize(settings.FONTSIZE)

        plt.savefig(settings.IMAGELOC + "ASL_ts{}".format(settings.OUTFMT))
        plt.close()

    #************************************************************************
    # Global maps

    # total
    if True:
        total = iris.load(DATALOC + "diffAOD.nc")  #.format(settings.YEAR))
        bounds = np.array([
            -10, -0.15, -0.10, -0.05, -0.025, -0.01, 0.01, 0.025, 0.05, 0.10,
            0.15, 10
        ])

        utils.plot_smooth_map_iris(
            settings.IMAGELOC + "ASL_total_anomalies_{}".format(settings.YEAR),
            total[0][0], settings.COLOURMAP_DICT["composition"], bounds,
            "Anomalies from 2003-{} (AOD)".format(settings.YEAR[2:]))
        utils.plot_smooth_map_iris(
            settings.IMAGELOC +
            "p2.1_ASL_total_anomalies_{}".format(settings.YEAR),
            total[0][0],
            settings.COLOURMAP_DICT["composition"],
            bounds,
            "Anomalies from 2003-20{} (AOD)".format(
                int(settings.YEAR[2:]) - 1),
            figtext="(x) Total Aerosol")

    # extreme AOD
    if True:
        extreme = iris.load(DATALOC + "NB999.nc")  #.format(settings.YEAR))
        bounds = np.array([0, 2.5, 5, 10, 20, 30, 40, 90])

        utils.plot_smooth_map_iris(
            settings.IMAGELOC + "ASL_extreme_days_{}".format(settings.YEAR),
            extreme[0][0], plt.cm.YlOrBr, bounds,
            "Number of days with AOD above the 99.9th percentile (days)")
        utils.plot_smooth_map_iris(
            settings.IMAGELOC +
            "p2.1_ASL_extreme_days_{}".format(settings.YEAR),
            extreme[0][0],
            plt.cm.YlOrBr,
            bounds,
            "Number of days with AOD above the 99.9th percentile (days)",
            figtext="(y) Extreme Aerosol Days")

    # Biomass Burning
    if False:
        BB = iris.load(DATALOC + "diffBB.nc")  #.format(settings.YEAR))

        utils.plot_smooth_map_iris(
            settings.IMAGELOC + "ASL_BB_anomalies_{}".format(settings.YEAR),
            BB[0], settings.COLOURMAP_DICT["composition"], bounds,
            "Anomalies from 2003-20{} (AOD)".format(
                int(settings.YEAR[2:]) - 1))
        utils.plot_smooth_map_iris(
            settings.IMAGELOC +
            "p2.1_ASL_BB_anomalies_{}".format(settings.YEAR),
            BB[0],
            settings.COLOURMAP_DICT["composition"],
            bounds,
            "Anomalies from 2003-20{} (AOD)".format(
                int(settings.YEAR[2:]) - 1),
            figtext="(y) Black Carbon & Organic Matter Aerosol")

    # Dust
    if False:
        dust = iris.load(DATALOC + "diffDU.nc")  #.format(settings.YEAR))

        utils.plot_smooth_map_iris(
            settings.IMAGELOC + "ASL_dust_anomalies_{}".format(settings.YEAR),
            dust[0], settings.COLOURMAP_DICT["composition"], bounds,
            "Anomalies from 2003-20{} (AOD)".format(
                int(settings.YEAR[2:]) - 1))
        utils.plot_smooth_map_iris(
            settings.IMAGELOC +
            "p2.1_ASL_dust_anomalies_{}".format(settings.YEAR),
            dust[0],
            settings.COLOURMAP_DICT["composition"],
            bounds,
            "Anomalies from 2003-20{} (AOD)".format(
                int(settings.YEAR[2:]) - 1),
            figtext="(z) Dust Aerosol")

    #************************************************************************
    # Total, Trend and Event map
    if False:

        # as one colorbar per map, don't use the utils Iris routine

        fig = plt.figure(figsize=(8, 15))

        #total = iris.load(DATALOC + "Aerosol_Fig2a_Total_Averages.nc")
        #trend = iris.load(DATALOC + "Aerosol_Fig2b_Total_Trends.nc")
        #event = iris.load(DATALOC + "Aerosol_Fig2c_ExtremeDayCounts_{}.nc".format(settings.YEAR))

        total = iris.load(DATALOC + "meanAOD.nc")
        trend = iris.load(DATALOC + "trend.nc")
        number = iris.load(DATALOC + "numbermonth.nc")

        bounds_a = np.array(
            [0, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.4, 0.5, 0.6, 0.7, 1.0])
        bounds_b = np.array([
            -10, -0.010, -0.005, -0.003, -0.002, -0.001, 0.001, 0.002, 0.003,
            0.005, 0.010, 10
        ])
        bounds_c = np.array([0, 1, 2, 3, 4, 5, 6, 7, 10])

        all_cubes = [total, trend, number]
        all_bounds = [bounds_a, bounds_b, bounds_c]

        # do colourmaps by hand
        cmap = [
            plt.cm.YlOrBr, settings.COLOURMAP_DICT["composition"],
            plt.cm.YlOrBr
        ]
        PLOTLABELS = ["(a)", "(b)", "(c)"]
        cb_label = ["AOD", "AOD yr" + r'$^{-1}$', "Months"]

        # spin through axes
        for a in range(3):

            norm = mpl.cm.colors.BoundaryNorm(all_bounds[a], cmap[a].N)

            ax = plt.subplot(3, 1, a + 1, projection=cartopy.crs.Robinson())

            ax.gridlines()  #draw_labels=True)
            ax.add_feature(cartopy.feature.LAND,
                           zorder=0,
                           facecolor="0.9",
                           edgecolor="k")
            ax.coastlines()

            ext = ax.get_extent()  # save the original extent

            mesh = iris.plot.pcolormesh(all_cubes[a][0],
                                        cmap=cmap[a],
                                        norm=norm,
                                        axes=ax)

            ax.set_extent(
                ext, ax.projection)  # fix the extent change from colormesh
            ax.text(0.0,
                    1.0,
                    PLOTLABELS[a],
                    fontsize=settings.FONTSIZE * 0.8,
                    transform=ax.transAxes)

            # sort the colourbar
            cb = fig.colorbar(mesh, ax=ax, orientation='horizontal', \
                                  ticks=all_bounds[a][1:-1], label=cb_label[a], drawedges=True, pad=0.05, fraction=0.07, aspect=30)
            if a == 1:
                cb.set_ticklabels(
                    ["{:6.3f}".format(b) for b in all_bounds[a][1:-1]])
            else:
                cb.set_ticklabels(
                    ["{:g}".format(b) for b in all_bounds[a][1:-1]])

            cb.outline.set_linewidth(2)
            cb.dividers.set_color('k')
            cb.dividers.set_linewidth(2)

        fig.subplots_adjust(bottom=0.05,
                            top=0.95,
                            left=0.04,
                            right=0.95,
                            wspace=0.02)

        plt.savefig(settings.IMAGELOC + "ASL_Trends{}".format(settings.OUTFMT))

        plt.close()

    #************************************************************************
    # Total, and two trends maps
    if True:

        # as one colorbar per map, don't use the utils Iris routine

        fig = plt.figure(figsize=(8, 15))

        total = iris.load(DATALOC + "AOD2003-2009.nc")[0]
        trend1 = iris.load(DATALOC + "trend2003-2019.nc")[0]
        trend1.data = np.ma.masked_where(trend1.data == -99, trend1.data)
        trend2 = iris.load(DATALOC + "medianaod12-19sig.nc")[0]
        trend2.data = np.ma.masked_where(trend2.data == -99, trend2.data)

        bounds_a = np.array(
            [0, 0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.4, 0.5, 0.6, 0.7, 1.0])
        bounds_b = np.array([
            -10, -0.020, -0.010, -0.006, -0.004, -0.002, 0.002, 0.004, 0.006,
            0.010, 0.020, 10
        ])
        bounds_c = np.array([
            -10, -0.020, -0.010, -0.006, -0.004, -0.002, 0.002, 0.004, 0.006,
            0.010, 0.020, 10
        ])

        all_cubes = [total, trend1, trend2]
        all_bounds = [bounds_a, bounds_b, bounds_c]

        # do colourmaps by hand
        cmap = [
            plt.cm.YlOrBr, settings.COLOURMAP_DICT["composition"],
            settings.COLOURMAP_DICT["composition"]
        ]
        PLOTLABELS = [
            "(a) Mean 2003-19", "(b) Trend 2003-19", "(c) Trend 2012-19"
        ]
        cb_label = ["AOD", "AOD yr" + r'$^{-1}$', "AOD yr" + r'$^{-1}$']

        # spin through axes
        for a in range(3):

            norm = mpl.cm.colors.BoundaryNorm(all_bounds[a], cmap[a].N)

            ax = plt.subplot(3, 1, a + 1, projection=cartopy.crs.Robinson())

            ax.gridlines()  #draw_labels=True)
            ax.add_feature(cartopy.feature.LAND,
                           zorder=0,
                           facecolor="0.9",
                           edgecolor="k")
            ax.coastlines()

            ext = ax.get_extent()  # save the original extent

            cube = all_cubes[a][0]
            if settings.OUTFMT in [".eps", ".pdf"]:
                if cube.coord("latitude").points.shape[0] > 180 or cube.coord(
                        "longitude").points.shape[0] > 360:
                    regrid_size = 1.0
                    print(
                        "Regridding cube for {} output to {} degree resolution"
                        .format(settings.OUTFMT, regrid_size))
                    print("Old Shape {}".format(cube.data.shape))
                    plot_cube = utils.regrid_cube(cube, regrid_size,
                                                  regrid_size)
                    print("New Shape {}".format(plot_cube.data.shape))
                else:
                    plot_cube = copy.deepcopy(cube)
            else:
                plot_cube = copy.deepcopy(cube)

            mesh = iris.plot.pcolormesh(plot_cube,
                                        cmap=cmap[a],
                                        norm=norm,
                                        axes=ax)

            ax.set_extent(
                ext, ax.projection)  # fix the extent change from colormesh
            ax.text(0.0,
                    1.0,
                    PLOTLABELS[a],
                    fontsize=settings.FONTSIZE * 0.8,
                    transform=ax.transAxes)

            # sort the colourbar
            cb = fig.colorbar(mesh, ax=ax, orientation='horizontal', \
                                  ticks=all_bounds[a][1:-1], label=cb_label[a], drawedges=True, pad=0.05, fraction=0.07, aspect=30)
            if a == 1:
                cb.set_ticklabels(
                    ["{:6.3f}".format(b) for b in all_bounds[a][1:-1]])
            else:
                cb.set_ticklabels(
                    ["{:g}".format(b) for b in all_bounds[a][1:-1]])

            cb.outline.set_linewidth(2)
            cb.dividers.set_color('k')
            cb.dividers.set_linewidth(2)

        fig.subplots_adjust(bottom=0.05,
                            top=0.95,
                            left=0.04,
                            right=0.95,
                            wspace=0.02)

        plt.savefig(settings.IMAGELOC + "ASL_Trends{}".format(settings.OUTFMT))

        plt.close()

    #************************************************************************
    # Forcing map
    if True:

        bounds = np.array([
            -10, -1.4, -1.0, -0.6, -0.4, -0.2, 0.0, 0.2, 0.4, 0.6, 1.0, 1.4, 10
        ])

        RFari = iris.load(
            DATALOC + "aerorf_camsra_rfari_2003-{}.nc".format(settings.YEAR))

        utils.plot_smooth_map_iris(
            settings.IMAGELOC + "ASL_RFari_anomalies_{}".format(settings.YEAR),
            RFari[0][0],
            settings.COLOURMAP_DICT["composition"],
            bounds,
            "Anomalies from 2003-{}".format(settings.YEAR),
            figtext="(a) CAMSRA: RFari (SW). Mean -0.56" + r'$\pm$' +
            "0.16 Wm" + r'$^{-1}$')

        RFaci = iris.load(
            DATALOC + "aerorf_camsra_rfaci_2003-{}.nc".format(settings.YEAR))

        utils.plot_smooth_map_iris(
            settings.IMAGELOC + "ASL_RFaci_anomalies_{}".format(settings.YEAR),
            RFaci[0][0],
            settings.COLOURMAP_DICT["composition"],
            bounds,
            "Anomalies from 2003-{}".format(settings.YEAR),
            figtext="(c) CAMSRA: RFaci (SW). Mean -0.80" + r'$\pm$' +
            "0.53 Wm" + r'$^{-1}$')

        # and timeseries
        cubelist = iris.load(
            DATALOC +
            "aerorf_camsra_timeseries_2003-{}.nc".format(settings.YEAR))

        LABELS = {"RFari": "(b)", "RFaci": "(d)"}
        ERRORS = {"RFari": 0.286, "RFaci": 0.667}

        for cube in cubelist:

            name = str(cube.var_name)
            name = name[:2].upper() + name[2:]

            fig = plt.figure(figsize=(8, 6))
            ax = plt.axes([0.13, 0.10, 0.8, 0.86])
            iris.plot.plot(cube, 'k', label=cube.var_name, lw=LW)

            timeUnits = cube.coord("time").units
            dt_time = timeUnits.num2date(cube.coord("time").points)
            upper = cube.data * (1 + ERRORS[name])
            lower = cube.data * (1 - ERRORS[name])
            ax.fill_between(dt_time, upper, lower, color="0.7", label=None)

            # prettify
            ax.set_ylabel("{} (W m".format(name) + r'$^{-2}$' + ")",
                          fontsize=settings.FONTSIZE)

            for tick in ax.yaxis.get_major_ticks():
                tick.label.set_fontsize(settings.FONTSIZE)
            for tick in ax.xaxis.get_major_ticks():
                tick.label.set_fontsize(settings.FONTSIZE)
            ax.yaxis.set_ticks_position('left')
            utils.thicken_panel_border(ax)

            minorLocator = MultipleLocator(365.242199)  # in days since
            ax.xaxis.set_minor_locator(minorLocator)
            utils.thicken_panel_border(ax)

            # set labels
            if cube.var_name == "rfari":
                ax.text(0.02, 0.9, "(b)")
                ax.set_ylim([-0.8, -0.3])
            else:
                ax.text(0.02, 0.9, "(d")
                ax.set_ylim([-1.6, -0.2])

            ax.text(0.02,
                    0.9,
                    LABELS[name],
                    transform=ax.transAxes,
                    fontsize=settings.FONTSIZE)

            plt.savefig(settings.IMAGELOC +
                        "ASL_ts_{}{}".format(cube.var_name, settings.OUTFMT))
            plt.close()

    return  # run_all_plots
예제 #3
0
def run_all_plots():

    if True:
        #***************
        # Figure 1

        euro, africa, tibet, canada = read_ts(DATALOC +
                                              "BAMS2020Fig1_data_LSWT.csv")
        #        euro_fit, africa_fit, tibet_fit, canada_fit = read_ts(DATALOC + "Fig1_lines_LSWT.csv")

        euro_fit = utils.Timeseries("Lake", [1994, 2020],
                                    [-0.5136, (2020 - 1994) * 0.0386 - 0.5136])
        africa_fit = utils.Timeseries(
            "Lake", [1994, 2020], [0.0204, (2020 - 1994) * 0.0036 + 0.0204])
        tibet_fit = utils.Timeseries("Lake", [1994, 2020],
                                     [0.0878, (2020 - 1994) * 0.0017 + 0.0878])
        canada_fit = utils.Timeseries(
            "Lake", [1994, 2020], [-0.2018, (2020 - 1994) * 0.0223 - 0.2018])

        fig, (ax1, ax2, ax3, ax4) = plt.subplots(4,
                                                 figsize=(8, 10),
                                                 sharex=True)

        #***************
        # the timeseries
        LEGEND_LOC = ""

        utils.plot_ts_panel(ax1, [euro], "-", "temperature", loc=LEGEND_LOC)
        ax1.plot(euro_fit.times,
                 euro_fit.data,
                 c=settings.COLOURS["temperature"][euro_fit.name],
                 lw=2,
                 ls="--")
        ax1.text(1995, 0.8, "Europe, 127 lakes", fontsize=settings.FONTSIZE)
        utils.plot_ts_panel(ax2, [africa], "-", "temperature", loc=LEGEND_LOC)
        ax2.plot(africa_fit.times,
                 africa_fit.data,
                 c=settings.COLOURS["temperature"][africa_fit.name],
                 lw=2,
                 ls="--")
        ax2.text(1995, 0.8, "Africa, 68 lakes", fontsize=settings.FONTSIZE)
        utils.plot_ts_panel(ax3, [tibet], "-", "temperature", loc=LEGEND_LOC)
        ax3.plot(tibet_fit.times,
                 tibet_fit.data,
                 c=settings.COLOURS["temperature"][tibet_fit.name],
                 lw=2,
                 ls="--")
        ax3.text(1995,
                 0.8,
                 "Tibetan Plateau, 106 lakes",
                 fontsize=settings.FONTSIZE)
        utils.plot_ts_panel(ax4, [canada], "-", "temperature", loc=LEGEND_LOC)
        ax4.plot(canada_fit.times,
                 canada_fit.data,
                 c=settings.COLOURS["temperature"][canada_fit.name],
                 lw=2,
                 ls="--")
        ax4.text(1995, 0.8, "Canada, 244 lakes", fontsize=settings.FONTSIZE)

        # prettify
        for ax in [ax1, ax2, ax3, ax4]:
            ax.axhline(0, c='0.5', ls='--')
            utils.thicken_panel_border(ax)
            ax.set_ylim([-1, 1.2])
            ax.set_xlim([euro.times[0] - 1, int(settings.YEAR) + 1])
            ax.yaxis.set_ticks_position('left')
            for tick in ax.yaxis.get_major_ticks():
                tick.label.set_fontsize(settings.FONTSIZE)
        for tick in ax4.xaxis.get_major_ticks():
            tick.label.set_fontsize(settings.FONTSIZE)

        fig.text(0.01,
                 0.35,
                 "Anomaly from 1996-2016 (" + r'$^\circ$' + "C)",
                 fontsize=settings.FONTSIZE,
                 rotation="vertical")
        fig.subplots_adjust(bottom=0.03, right=0.96, top=0.99, hspace=0.001)

        plt.savefig(settings.IMAGELOC + "LKT_ts{}".format(settings.OUTFMT))

        plt.close()

    #***************
    # Anomaly Scatter map
    if True:
        anomalies = read_lakes(DATALOC + "PlateX_data_LSWT.csv")

        bounds = [-8, -2, -1.5, -1.0, -0.5, 0, 0.5, 1.0, 1.5, 2, 8]
        #        bounds = [-100, -4, -2, -1, -0.5, 0, 0.5, 1, 2, 4, 100]

        lons = np.arange(-90, 120, 30)
        lats = np.arange(-180, 210, 30)
        dummy = np.ma.zeros((len(lats), len(lons)))
        dummy.mask = np.ones(dummy.shape)

        cube = utils.make_iris_cube_2d(dummy, lats, lons, "blank", "m")

        utils.plot_smooth_map_iris(settings.IMAGELOC + "LKT_anomaly", cube, settings.COLOURMAP_DICT["temperature"], \
                                       bounds, "Anomalies from 1996-2016 ("+r"$^{\circ}$"+"C)", \
                                       scatter=[anomalies[1], anomalies[0], anomalies[2]], figtext="", title="")

        utils.plot_smooth_map_iris(settings.IMAGELOC + "p2.1_LKT_anomaly", cube, settings.COLOURMAP_DICT["temperature"], \
                                       bounds, "Anomalies from 1996-2016 ("+r"$^{\circ}$"+"C)", \
                                       scatter=[anomalies[1], anomalies[0], anomalies[2]], \
                                       figtext="(b) Lake Temperatures", title="")

    #***************
    # Insets Scatter map
    if True:

        fig = plt.figure(figsize=(8, 7))
        plt.clf()

        anomalies = read_lakes(DATALOC + "Fig2_data_LSWT.csv")

        bounds = [-8, -2, -1.5, -1.0, -0.5, 0, 0.5, 1.0, 1.5, 2, 8]
        #        bounds = [-100, -4, -2, -1, -0.5, 0, 0.5, 1, 2, 4, 100]
        cmap = settings.COLOURMAP_DICT["temperature"]
        norm = mpl.cm.colors.BoundaryNorm(bounds, cmap.N)
        this_cmap = copy.copy(cmap)

        # first_cube = iris.load(DATALOC + "amaps_1st_quarter_2018_250km.nc")[0]
        # third_cube = iris.load(DATALOC + "amaps_3rd_quarter_2018_250km.nc")[0]
        # annual_cube = iris.load(DATALOC + "amaps_annual_2018_250km.nc")[0]

        cube = iris.load(DATALOC + "lswt_anom_1979_2019.nc")[0]
        if settings.OUTFMT in [".eps", ".pdf"]:
            if cube.coord("latitude").points.shape[0] > 180 or cube.coord(
                    "longitude").points.shape[0] > 360:
                regrid_size = 1.0
                print("Regridding cube for {} output to {} degree resolution".
                      format(settings.OUTFMT, regrid_size))
                print("Old Shape {}".format(cube.data.shape))
                plot_cube = utils.regrid_cube(cube, regrid_size, regrid_size)
                print("New Shape {}".format(plot_cube.data.shape))
            else:
                plot_cube = copy.deepcopy(cube)
        else:
            plot_cube = copy.deepcopy(cube)

        # make axes by hand
        axes = ([0.01, 0.55, 0.59,
                 0.41], [0.565, 0.45, 0.47,
                         0.50], [0.01, 0.13, 0.59,
                                 0.41], [0.61, 0.07, 0.38,
                                         0.41], [0.1, 0.1, 0.8, 0.03])

        # Europe
        ax = plt.axes(axes[0], projection=cartopy.crs.PlateCarree())

        ax.gridlines()  #draw_labels=True)
        ax.add_feature(cartopy.feature.LAND,
                       zorder=0,
                       facecolor="0.9",
                       edgecolor="k")
        ax.coastlines(resolution="50m")
        #ax.add_feature(cartopy.feature.BORDERS.with_scale('110m'), linewidth=.5)
        ax.set_extent([-25, 40, 34, 72], cartopy.crs.PlateCarree())

        mesh = iris.plot.pcolormesh(plot_cube,
                                    cmap=this_cmap,
                                    norm=norm,
                                    axes=ax)
        plt.scatter(anomalies[1], anomalies[0], c=anomalies[2], cmap=this_cmap, norm=norm, s=25, \
                                transform=cartopy.crs.Geodetic(), edgecolor='0.1', linewidth=0.5, zorder=10)

        ax.text(0.05,
                1.05,
                "(a) Europe",
                fontsize=settings.FONTSIZE * 0.8,
                transform=ax.transAxes)
        utils.thicken_panel_border(ax)

        # Africa
        ax = plt.axes(axes[1], projection=cartopy.crs.PlateCarree())

        ax.gridlines()  #draw_labels=True)
        ax.add_feature(cartopy.feature.LAND,
                       zorder=0,
                       facecolor="0.9",
                       edgecolor="k")
        ax.coastlines(resolution="50m")
        #ax.add_feature(cartopy.feature.BORDERS.with_scale('110m'), linewidth=.5)
        ax.set_extent([-19, 43, -40, 33], cartopy.crs.PlateCarree())

        # lat_constraint = utils.latConstraint([25, 90])
        # nh_cube = third_cube.extract(lat_constraint)
        # lat_constraint = utils.latConstraint([-90, -25])
        # sh_cube = first_cube.extract(lat_constraint)
        # lat_constraint = utils.latConstraint([-25, 25])
        # trop_cube = annual_cube.extract(lat_constraint)

        # mesh = iris.plot.pcolormesh(nh_cube, cmap=this_cmap, norm=norm, axes=ax)
        # mesh = iris.plot.pcolormesh(trop_cube, cmap=this_cmap, norm=norm, axes=ax)
        # mesh = iris.plot.pcolormesh(sh_cube, cmap=this_cmap, norm=norm, axes=ax)
        mesh = iris.plot.pcolormesh(plot_cube,
                                    cmap=this_cmap,
                                    norm=norm,
                                    axes=ax)

        plt.scatter(anomalies[1], anomalies[0], c=anomalies[2], cmap=this_cmap, norm=norm, s=25, \
                                transform=cartopy.crs.Geodetic(), edgecolor='0.1', linewidth=0.5, zorder=10)

        ax.text(0.05,
                1.05,
                "(b) Africa",
                fontsize=settings.FONTSIZE * 0.8,
                transform=ax.transAxes)
        utils.thicken_panel_border(ax)

        # Canada
        ax = plt.axes(axes[2], projection=cartopy.crs.PlateCarree())

        ax.gridlines()  #draw_labels=True)
        ax.add_feature(cartopy.feature.LAND,
                       zorder=0,
                       facecolor="0.9",
                       edgecolor="k")
        ax.coastlines(resolution="50m")
        #ax.add_feature(cartopy.feature.BORDERS.with_scale('110m'), linewidth=.5)
        ax.set_extent([-140, -55, 42, 82], cartopy.crs.PlateCarree())

        mesh = iris.plot.pcolormesh(plot_cube,
                                    cmap=this_cmap,
                                    norm=norm,
                                    axes=ax)
        plt.scatter(anomalies[1], anomalies[0], c=anomalies[2], cmap=this_cmap, norm=norm, s=25, \
                                transform=cartopy.crs.Geodetic(), edgecolor='0.1', linewidth=0.5, zorder=10)

        ax.text(0.05,
                1.05,
                "(c) Canada",
                fontsize=settings.FONTSIZE * 0.8,
                transform=ax.transAxes)
        utils.thicken_panel_border(ax)

        # Tibet
        ax = plt.axes(axes[3], projection=cartopy.crs.PlateCarree())

        ax.gridlines()  #draw_labels=True)
        ax.add_feature(cartopy.feature.LAND,
                       zorder=0,
                       facecolor="0.9",
                       edgecolor="k")
        ax.coastlines(resolution="50m")
        ax.add_feature(cartopy.feature.BORDERS.with_scale('50m'), linewidth=.5)
        ax.set_extent([78, 102, 28, 39], cartopy.crs.PlateCarree())

        mesh = iris.plot.pcolormesh(plot_cube,
                                    cmap=this_cmap,
                                    norm=norm,
                                    axes=ax)
        plt.scatter(anomalies[1], anomalies[0], c=anomalies[2], cmap=this_cmap, norm=norm, s=25, \
                                transform=cartopy.crs.Geodetic(), edgecolor='0.1', linewidth=0.5, zorder=10)

        ax.text(0.05,
                1.05,
                "(d) Tibetan Plateau",
                fontsize=settings.FONTSIZE * 0.8,
                transform=ax.transAxes)
        utils.thicken_panel_border(ax)

        # colourbar
        cb = plt.colorbar(mesh,
                          cax=plt.axes(axes[4]),
                          orientation='horizontal',
                          ticks=bounds[1:-1],
                          drawedges=True)

        # prettify
        cb.ax.tick_params(axis='x',
                          labelsize=settings.FONTSIZE,
                          direction='in',
                          size=0)
        cb.set_label(label="Anomalies from 1996-2016 (" + r"$^{\circ}$" + "C)",
                     fontsize=settings.FONTSIZE)
        cb.set_ticklabels(["{:g}".format(b) for b in bounds[1:-1]])
        cb.outline.set_linewidth(2)
        cb.dividers.set_color('k')
        cb.dividers.set_linewidth(2)

        plt.savefig(settings.IMAGELOC +
                    "LKT_Regions_scatter_map{}".format(settings.OUTFMT))
        plt.close()
예제 #4
0
def run_all_plots():

    #***********************
    # MODIS - centre
    if True:
        cubelist = iris.load(
            os.path.join(
                DATALOC,
                "MODIS.CMG.{}.SOS.EOS.Anomaly.nc".format(settings.YEAR)))
        names = np.array([c.name() for c in cubelist])
        # set up plot settings
        BOUNDS = [-100, -20, -10, -5, -2, 0, 2, 5, 10, 20, 100]
        LABELS = {
            "SOS": "(c) Start of Season (SOS)",
            "EOS": "(d) End of Season (EOS)"
        }

        for season in ["SOS", "EOS"]:

            c, = np.where(names == season)[0]

            cube = cubelist[c]

            # deal with NANS
            cube.data = np.ma.masked_where(cube.data != cube.data, cube.data)

            fig = plt.figure(figsize=(8, 11))
            plt.clf()

            # boundary circle
            theta = np.linspace(0, 2 * np.pi, 100)
            center, radius = [0.5, 0.5], 0.5
            verts = np.vstack([np.sin(theta), np.cos(theta)]).T
            circle = mpath.Path(verts * radius + center)

            # axes for polar plot
            ax = plt.axes([0.01, 0.02, 0.98, 0.65],
                          projection=cartopy.crs.NorthPolarStereo(
                              central_longitude=300.0))

            plot_cube = cube

            # regrid depending on output format
            if settings.OUTFMT in [".eps", ".pdf"]:
                if plot_cube.coord(
                        "latitude").points.shape[0] > 90 or plot_cube.coord(
                            "longitude").points.shape[0] > 360:
                    regrid_size = 1.0
                    print(
                        "Regridding cube for {} output to {} degree resolution"
                        .format(settings.OUTFMT, regrid_size))
                    print("Old Shape {}".format(plot_cube.data.shape))
                    plot_cube = utils.regrid_cube(plot_cube, regrid_size,
                                                  regrid_size)
                    print("New Shape {}".format(plot_cube.data.shape))

            # prettify
            ax.gridlines()  #draw_labels=True)
            ax.add_feature(cartopy.feature.LAND,
                           zorder=0,
                           facecolor="0.9",
                           edgecolor="k")
            ax.coastlines()
            ax.set_boundary(circle, transform=ax.transAxes)

            if season == "SOS":
                cmap = settings.COLOURMAP_DICT["phenological_r"]
            elif season == "EOS":
                cmap = settings.COLOURMAP_DICT["phenological"]

            norm = mpl.cm.colors.BoundaryNorm(BOUNDS, cmap.N)
            mesh = iris.plot.pcolormesh(plot_cube,
                                        cmap=cmap,
                                        norm=norm,
                                        axes=ax)

            # # read in sites
            if season == "EOS":
                pass
            elif season == "SOS":
                lake_locations = read_us_phenocam(
                    os.path.join(DATALOC, "lake_coords.csv"))
                # scatter
                COL = "chartreuse"
                ax.scatter(lake_locations[1],
                           lake_locations[0],
                           c=COL,
                           s=100,
                           edgecolor="k",
                           transform=cartopy.crs.Geodetic(),
                           zorder=10)
                COL = "m"
                # Harvard Forest - 2019
                ax.scatter(-72.17,
                           42.54,
                           c=COL,
                           s=100,
                           edgecolor="k",
                           transform=cartopy.crs.Geodetic(),
                           zorder=10)

                # uk box
                COL = "y"
                region = [-10.0, 49.0, 3.0, 60.0]
                ax.plot([region[0], region[0]], [region[1], region[3]],
                        c=COL,
                        ls='-',
                        lw=4,
                        zorder=10,
                        transform=cartopy.crs.PlateCarree())
                ax.plot([region[2], region[2]], [region[1], region[3]],
                        c=COL,
                        ls='-',
                        lw=4,
                        zorder=10,
                        transform=cartopy.crs.PlateCarree())
                ax.plot([region[0], region[2]], [region[1], region[1]],
                        c=COL,
                        ls='-',
                        lw=4,
                        zorder=10,
                        transform=cartopy.crs.Geodetic())
                ax.plot([region[0], region[2]], [region[3], region[3]],
                        c=COL,
                        ls='-',
                        lw=4,
                        zorder=10,
                        transform=cartopy.crs.Geodetic())

            # COL = "k"
            # ax.plot([region[0], region[0]], [region[1], region[3]], c=COL, ls='-', lw=5, zorder=9, transform=cartopy.crs.PlateCarree())
            # ax.plot([region[2], region[2]], [region[1], region[3]], c=COL, ls='-', lw=5, zorder=9, transform=cartopy.crs.PlateCarree())
            # ax.plot([region[0], region[2]], [region[1], region[1]], c=COL, ls='-', lw=5, zorder=9, transform=cartopy.crs.Geodetic())
            # ax.plot([region[0], region[2]], [region[3], region[3]], c=COL, ls='-', lw=5, zorder=9, transform=cartopy.crs.Geodetic())

            # label axes
            ax.text(-0.1,
                    1.0,
                    LABELS[season],
                    fontsize=settings.FONTSIZE,
                    transform=ax.transAxes)

            cb = plt.colorbar(mesh,
                              orientation='horizontal',
                              ticks=BOUNDS[1:-1],
                              drawedges=True,
                              fraction=0.1,
                              pad=0.01,
                              aspect=20,
                              shrink=0.8)
            # prettify
            cb.set_label(label="Anomaly (days)", fontsize=settings.FONTSIZE)
            cb.ax.tick_params(axis='x',
                              labelsize=settings.FONTSIZE,
                              direction='in',
                              size=0)
            cb.set_ticklabels(["{:g}".format(b) for b in BOUNDS[1:-1]])
            cb.outline.set_linewidth(2)
            cb.dividers.set_color('k')
            cb.dividers.set_linewidth(2)

            ax.set_extent([-180, 180, 30, 90], cartopy.crs.PlateCarree())

            for lat in range(30, 100, 10):
                ax.text(180,
                        lat,
                        '{}$^\circ$N'.format(lat),
                        transform=cartopy.crs.Geodetic())

            fig.subplots_adjust(bottom=0.05,
                                top=0.95,
                                left=0.04,
                                right=0.95,
                                wspace=0.02)

            del cube

            #***********************
            # MODIS timeserise
            sos_nh, eos_nh, sprt_nh_orig, falt_nh_orig = read_modis_ts(
                os.path.join(
                    DATALOC, "MODIS.CMG.{}.SOS.EOS.SPRT.FALT.TS.csv".format(
                        settings.YEAR)))

            dummy, sos_nh = utils.calculate_climatology_and_anomalies_1d(
                sos_nh, 2000, 2010)
            dummy, eos_nh = utils.calculate_climatology_and_anomalies_1d(
                eos_nh, 2000, 2010)

            dummy, sprt_nh = utils.calculate_climatology_and_anomalies_1d(
                sprt_nh_orig, 2000, 2010)
            dummy, falt_nh = utils.calculate_climatology_and_anomalies_1d(
                falt_nh_orig, 2000, 2010)

            ax = plt.axes([0.15, 0.73, 0.75, 0.23])
            if season == "SOS":
                label = "(a) Start of Season"
                anomalies = [
                    "{} SOS Anomaly = -4.3 days".format(settings.YEAR),
                    "{} Spr. T anomaly = 0.19 ".format(settings.YEAR) +
                    r'$^{\circ}$' + "C"
                ]

                plot_modis_ts(ax, sos_nh, sprt_nh, sprt_nh_orig, label,
                              anomalies, LEGEND_LOC)

            elif season == "EOS":
                label = "(b) End of Season"
                anomalies = [
                    "{} EOS Anomaly = 2.4 days".format(settings.YEAR),
                    "{} Fall T anomaly = -0.53 ".format(settings.YEAR) +
                    r'$^{\circ}$' + "C"
                ]

                plot_modis_ts(ax, eos_nh, falt_nh, falt_nh_orig, label,
                              anomalies, LEGEND_LOC)

            plt.savefig(settings.IMAGELOC + "PHEN_modis_{}_{}{}".format(
                settings.YEAR, season, settings.OUTFMT))

        del cubelist

#***********************
# US timeseries - 2018
    if True:
        fig = plt.figure(figsize=(8, 9.5))
        plt.clf()

        modis_sos, modis_eos, pheno_sos, pheno_eos = read_us_phenocam_csv(
            os.path.join(DATALOC, "Richardson Data for SOC 2019 Figures.csv"))

        # images
        ax = plt.axes([0.01, 0.66, 0.49, 0.3])
        plot_images(ax, "HarvardForest_20190511.jpg")
        ax = plt.axes([0.5, 0.66, 0.49, 0.3])
        plot_images(ax, "HarvardForest_20191024.jpg")

        # timeseries
        ax = plt.axes([0.11, 0.35, 0.84, 0.3])
        plot_us_phenocam(ax, modis_eos, pheno_eos, sos=False)
        #        ax.text(0.05, 0.85, "(a)", transform=ax.transAxes, fontsize=settings.FONTSIZE)
        ax.set_ylim([275, 369])
        plt.setp(ax.get_xticklabels(), visible=False)

        ax = plt.axes([0.11, 0.05, 0.84, 0.3])
        plot_us_phenocam(ax, modis_sos, pheno_sos)
        #        ax.text(0.05, 0.85, "(b)", transform=ax.transAxes, fontsize=settings.FONTSIZE)
        ax.set_ylim([101, 144])

        fig.text(0.02,
                 0.97,
                 "(a)",
                 transform=ax.transAxes,
                 fontsize=settings.FONTSIZE)
        fig.text(0.02,
                 0.3,
                 "Day of year",
                 rotation="vertical",
                 fontsize=settings.FONTSIZE)
        plt.savefig(
            settings.IMAGELOC +
            "PHEN_UStimeseries_{}{}".format(settings.YEAR, settings.OUTFMT))
        plt.close()

    #***********************
    # US timeseries - 2018
    if False:
        fig = plt.figure(figsize=(8, 7))
        plt.clf()

        modis_sos, modis_eos, pheno_sos, pheno_eos = read_us_phenocam_csv(
            os.path.join(DATALOC, "Richardson Data for SOC 2019 Figures.csv"))

        # timeseries
        ax = plt.axes([0.11, 0.5, 0.64, 0.45])
        plot_us_phenocam(ax, modis_eos, pheno_eos, sos=False)
        ax.text(0.05,
                0.85,
                "(c)",
                transform=ax.transAxes,
                fontsize=settings.FONTSIZE)
        ax.set_ylim([275, 369])
        plt.setp(ax.get_xticklabels(), visible=False)
        ax = plt.axes([0.75, 0.5, 0.25, 0.4])
        plot_images(ax, "HarvardForest_20191024.jpg")

        ax = plt.axes([0.11, 0.05, 0.64, 0.45])
        plot_us_phenocam(ax, modis_sos, pheno_sos)
        ax.text(0.05,
                0.85,
                "(d)",
                transform=ax.transAxes,
                fontsize=settings.FONTSIZE)
        ax.set_ylim([101, 144])
        ax = plt.axes([0.75, 0.05, 0.25, 0.4])
        plot_images(ax, "HarvardForest_20190511.jpg")

        fig.text(0.02,
                 0.4,
                 "Day of year",
                 rotation="vertical",
                 fontsize=settings.FONTSIZE)
        plt.savefig(
            settings.IMAGELOC +
            "PHEN_UStimeseries_{}{}".format(settings.YEAR, settings.OUTFMT))
        plt.close()

    #***********************
    # UK timeseries - 2018
    if True:
        from matplotlib.ticker import MultipleLocator
        majorLocator = MultipleLocator(5)

        fig = plt.figure(figsize=(8, 9.5))
        plt.clf()

        # images
        ax = plt.axes([0.01, 0.66, 0.48, 0.3])
        plot_images(ax, "Sarah Burgess first leaf.jpg")
        ax = plt.axes([0.5, 0.66, 0.48, 0.3])
        plot_images(ax, "Judith Garforth oak bare tree 2019.jpg")

        sos_uk, eos_uk = read_modis_uk_ts(
            os.path.join(
                DATALOC, "MODIS.CMG.{}.SOS.EOS.SPRT.FALT.TS.UK_DH.csv".format(
                    settings.YEAR)))
        oak_sos, oak_eos = read_uk_oak_csv(
            os.path.join(DATALOC, "UK_Oakleaf_data.csv"))

        # timeseries
        ax = plt.axes([0.11, 0.35, 0.84, 0.3])
        utils.plot_ts_panel(ax, [oak_eos, eos_uk],
                            "-",
                            "phenological",
                            loc="center left")
        #        ax.text(0.05, 0.85, "(c)", transform=ax.transAxes, fontsize=settings.FONTSIZE)
        ax.set_ylim([210, 354])
        plt.setp(ax.get_xticklabels(), visible=False)
        for tick in ax.xaxis.get_major_ticks():
            tick.label.set_fontsize(settings.FONTSIZE)
        for tick in ax.yaxis.get_major_ticks():
            tick.label.set_fontsize(settings.FONTSIZE)
        ax.xaxis.set_major_locator(majorLocator)

        # naughtily, manually tweak the upper oak plot
        for line in ax.get_lines():
            if line.get_color() == "g":
                line.set_color("#d95f0e")
        leg = ax.get_legend()
        for line in leg.get_lines():
            if line.get_color() == "g":
                line.set_color("#d95f0e")

        ax = plt.axes([0.11, 0.05, 0.84, 0.3])
        utils.plot_ts_panel(ax, [oak_sos, sos_uk],
                            "-",
                            "phenological",
                            loc="center left")
        #        ax.text(0.05, 0.85, "(d)", transform=ax.transAxes, fontsize=settings.FONTSIZE)
        ax.set_ylim([66, 132])
        for tick in ax.xaxis.get_major_ticks():
            tick.label.set_fontsize(settings.FONTSIZE)
        for tick in ax.yaxis.get_major_ticks():
            tick.label.set_fontsize(settings.FONTSIZE)
        ax.xaxis.set_major_locator(majorLocator)

        fig.text(0.02,
                 0.97,
                 "(b)",
                 transform=ax.transAxes,
                 fontsize=settings.FONTSIZE)
        fig.text(0.02,
                 0.3,
                 "Day of year",
                 rotation="vertical",
                 fontsize=settings.FONTSIZE)

        plt.savefig(
            settings.IMAGELOC +
            "PHEN_UKtimeseries_{}{}".format(settings.YEAR, settings.OUTFMT))
        plt.close()

    #***********************
    # Lake Boxplot
    if True:

        import pandas as pd

        df = pd.read_csv(DATALOC + "LakeData_forRobert.csv")

        # rename columns
        cols = []
        for col in df.columns:
            if len(col.split()) >= 2:
                df.rename(columns={col: col.split()[0]}, inplace=True)
                cols += [col.split()[0]]

        fig = plt.figure(figsize=(8, 7))
        plt.clf()
        ax = plt.axes([0.1, 0.25, 0.89, 0.74])
        df.boxplot(
            column=cols,
            ax=ax,
            grid=False,
        )

        # messily pull out 2019
        this_year = df.iloc[-1]
        this_year = this_year.to_frame()
        plt.plot(np.arange(11) + 1, this_year[19][1:], "ro")

        for tick in ax.xaxis.get_major_ticks():
            tick.label.set_fontsize(settings.FONTSIZE)
            tick.label.set_rotation("vertical")

        for tick in ax.yaxis.get_major_ticks():
            tick.label.set_fontsize(settings.FONTSIZE)

        utils.thicken_panel_border(ax)

        plt.ylabel("Day of year", fontsize=settings.FONTSIZE)
        plt.savefig(
            settings.IMAGELOC +
            "PHEN_lakes_boxplot_{}{}".format(settings.YEAR, settings.OUTFMT))
        plt.close()

    return  # run_all_plots
예제 #5
0
def run_all_plots():

    cubelist = iris.load(
        os.path.join(DATALOC,
                     "era5_lic_anom_1979_2019_NH.nc".format(settings.YEAR)))
    names = np.array([c.name() for c in cubelist])

    LABELS = {
        "Ice Start": "(a) Ice On",
        "Ice End": "(b) Ice Off",
        "Ice Duration": "(c) Ice Duration"
    }
    COLORS = {
        "Ice Start": plt.cm.RdBu_r,
        "Ice End": plt.cm.RdBu,
        "Ice Duration": plt.cm.RdBu
    }

    BOUNDS = [-100, -20, -10, -5, -2, 0, 2, 5, 10, 20, 100]

    for name in names:
        if name == "Ice Depth":
            continue

        c, = np.where(names == name)[0]

        cube = cubelist[c]

        fig = plt.figure(figsize=(8, 9.5))
        plt.clf()

        # boundary circle
        theta = np.linspace(0, 2 * np.pi, 100)
        center, radius = [0.5, 0.5], 0.5
        verts = np.vstack([np.sin(theta), np.cos(theta)]).T
        circle = mpath.Path(verts * radius + center)

        # axes for polar plot
        ax = plt.axes(
            [0.01, 0.02, 0.98, 0.98],
            projection=cartopy.crs.NorthPolarStereo(central_longitude=300.0))

        plot_cube = cube

        # regrid depending on output format
        if settings.OUTFMT in [".eps", ".pdf"]:
            if plot_cube.coord(
                    "latitude").points.shape[0] > 90 or plot_cube.coord(
                        "longitude").points.shape[0] > 360:
                regrid_size = 1.0
                print("Regridding cube for {} output to {} degree resolution".
                      format(settings.OUTFMT, regrid_size))
                print("Old Shape {}".format(plot_cube.data.shape))
                plot_cube = utils.regrid_cube(plot_cube, regrid_size,
                                              regrid_size)
                print("New Shape {}".format(plot_cube.data.shape))

        # prettify
        ax.gridlines()  #draw_labels=True)
        ax.add_feature(cartopy.feature.LAND,
                       zorder=0,
                       facecolor="0.9",
                       edgecolor="k")
        ax.coastlines()
        ax.set_boundary(circle, transform=ax.transAxes)

        cmap = COLORS[name]
        norm = mpl.cm.colors.BoundaryNorm(BOUNDS, cmap.N)
        mesh = iris.plot.pcolormesh(plot_cube, cmap=cmap, norm=norm, axes=ax)

        # label axes
        ax.text(0.01,
                1.0,
                "{}".format(LABELS[name]),
                fontsize=settings.FONTSIZE,
                transform=ax.transAxes)

        cb = plt.colorbar(mesh,
                          orientation='horizontal',
                          ticks=BOUNDS[1:-1],
                          drawedges=True,
                          fraction=0.1,
                          pad=0.01,
                          aspect=20,
                          shrink=0.8)
        # prettify
        cb.set_label(label="Anomaly (days)", fontsize=settings.FONTSIZE)
        cb.ax.tick_params(axis='x',
                          labelsize=settings.FONTSIZE,
                          direction='in',
                          size=0)
        cb.set_ticklabels(["{:g}".format(b) for b in BOUNDS[1:-1]])
        cb.outline.set_linewidth(2)
        cb.dividers.set_color('k')
        cb.dividers.set_linewidth(2)

        ax.set_extent([-180, 180, 30, 90], cartopy.crs.PlateCarree())

        for lat in range(30, 100, 10):
            ax.text(180,
                    lat,
                    '{}$^\circ$N'.format(lat),
                    transform=cartopy.crs.Geodetic())

        plt.savefig(settings.IMAGELOC + "LIC_map_{}_{}{}".format(
            settings.YEAR, "".join(name.split()), settings.OUTFMT))

    #************************************************************************
    # and temperatures
    BOUNDS = [-100, -4, -3, -2, -1, 0, 1, 2, 3, 4, 100]
    cubelist = iris.load(os.path.join(DATALOC, "amaps.nc"))

    cube = cubelist[0]

    fig = plt.figure(figsize=(8, 9.5))
    plt.clf()

    # boundary circle
    theta = np.linspace(0, 2 * np.pi, 100)
    center, radius = [0.5, 0.5], 0.5
    verts = np.vstack([np.sin(theta), np.cos(theta)]).T
    circle = mpath.Path(verts * radius + center)

    # axes for polar plot
    ax = plt.axes(
        [0.01, 0.02, 0.98, 0.98],
        projection=cartopy.crs.NorthPolarStereo(central_longitude=300.0))

    plot_cube = cube

    # regrid depending on output format
    if settings.OUTFMT in [".eps", ".pdf"]:
        if plot_cube.coord("latitude").points.shape[0] > 90 or plot_cube.coord(
                "longitude").points.shape[0] > 360:
            regrid_size = 1.0
            print(
                "Regridding cube for {} output to {} degree resolution".format(
                    settings.OUTFMT, regrid_size))
            print("Old Shape {}".format(plot_cube.data.shape))
            plot_cube = utils.regrid_cube(plot_cube, regrid_size, regrid_size)
            print("New Shape {}".format(plot_cube.data.shape))

    # prettify
    ax.gridlines()  #draw_labels=True)
    ax.add_feature(cartopy.feature.LAND,
                   zorder=0,
                   facecolor="0.9",
                   edgecolor="k")
    ax.coastlines()
    ax.set_boundary(circle, transform=ax.transAxes)

    cmap = plt.cm.RdBu_r
    norm = mpl.cm.colors.BoundaryNorm(BOUNDS, cmap.N)
    mesh = iris.plot.pcolormesh(plot_cube, cmap=cmap, norm=norm, axes=ax)

    # label axes
    ax.text(0.01,
            1.0,
            "(d) Nov-Apr Air Temperature",
            fontsize=settings.FONTSIZE,
            transform=ax.transAxes)

    cb = plt.colorbar(mesh,
                      orientation='horizontal',
                      ticks=BOUNDS[1:-1],
                      drawedges=True,
                      fraction=0.1,
                      pad=0.01,
                      aspect=20,
                      shrink=0.8)
    # prettify
    cb.set_label(label="Anomaly ($^\circ$C)", fontsize=settings.FONTSIZE)
    cb.ax.tick_params(axis='x',
                      labelsize=settings.FONTSIZE,
                      direction='in',
                      size=0)
    cb.set_ticklabels(["{:g}".format(b) for b in BOUNDS[1:-1]])
    cb.outline.set_linewidth(2)
    cb.dividers.set_color('k')
    cb.dividers.set_linewidth(2)

    ax.set_extent([-180, 180, 30, 90], cartopy.crs.PlateCarree())

    for lat in range(30, 100, 10):
        ax.text(180,
                lat,
                '{}$^\circ$N'.format(lat),
                transform=cartopy.crs.Geodetic())

    plt.savefig(
        settings.IMAGELOC +
        "LIC_map_{}_{}{}".format(settings.YEAR, "AirT", settings.OUTFMT))

    #************************************************************************
    # Timeseries
    era_start, era_end, era_length = read_column_csv(
        os.path.join(DATALOC,
                     "era5_lic_anom_1979_{}_NH.csv".format(settings.YEAR)))
    situ_start, situ_end, situ_length = read_column_csv(os.path.join(
        DATALOC, "situ_lic_anom_1979_{}_NH.csv".format(settings.YEAR)),
                                                        era=False)

    plt.clf()
    fig, (ax1, ax2, ax3) = plt.subplots(3, figsize=(8, 10), sharex=True)

    # start
    utils.plot_ts_panel(ax1, [era_start, situ_start],
                        "-",
                        "cryosphere",
                        loc="")

    # end
    utils.plot_ts_panel(ax2, [era_end, situ_end], "-", "cryosphere", loc="")
    ax2.set_ylabel("Anomaly (day)", fontsize=settings.FONTSIZE)

    # duration
    utils.plot_ts_panel(ax3, [era_length, situ_length],
                        "-",
                        "cryosphere",
                        loc="lower left")

    # sort formatting
    for tick in ax3.xaxis.get_major_ticks():
        tick.label.set_fontsize(settings.FONTSIZE)

    for tick in ax1.yaxis.get_major_ticks():
        tick.label.set_fontsize(settings.FONTSIZE)
    for tick in ax2.yaxis.get_major_ticks():
        tick.label.set_fontsize(settings.FONTSIZE)
    for tick in ax3.yaxis.get_major_ticks():
        tick.label.set_fontsize(settings.FONTSIZE)

    # sort labelling
    ax1.text(0.02,
             0.9,
             "(a) Start of Ice Cover",
             transform=ax1.transAxes,
             fontsize=settings.LABEL_FONTSIZE)
    ax2.text(0.02,
             0.9,
             "(b) End of Ice Cover",
             transform=ax2.transAxes,
             fontsize=settings.LABEL_FONTSIZE)
    ax3.text(0.02,
             0.9,
             "(c) Duration of Ice Cover",
             transform=ax3.transAxes,
             fontsize=settings.LABEL_FONTSIZE)

    fig.subplots_adjust(bottom=0.05, right=0.95, top=0.95, hspace=0.001)

    plt.savefig(settings.IMAGELOC +
                "LIC_ts_{}{}".format(settings.YEAR, settings.OUTFMT))

    #************************************************************************
    # Timeseries
    indata = read_continuous_csv(os.path.join(DATALOC, "great_lakes_anom.csv"))

    fig = plt.figure(figsize=(8, 6))
    plt.clf()
    ax = plt.axes([0.1, 0.05, 0.88, 0.9])

    utils.plot_ts_panel(ax, indata, "-", "cryosphere", loc="")

    fig.text(0.02,
             0.5,
             "Maximum ice cover (anomaly, %)",
             va='center',
             rotation='vertical',
             ha="center",
             fontsize=settings.FONTSIZE)

    for tick in ax.yaxis.get_major_ticks():
        tick.label.set_fontsize(settings.FONTSIZE)
    for tick in ax.xaxis.get_major_ticks():
        tick.label.set_fontsize(settings.FONTSIZE)

    plt.savefig(settings.IMAGELOC +
                "LIC_GL_ts_{}{}".format(settings.YEAR, settings.OUTFMT))

    return  # run_all_plots
예제 #6
0
def run_all_plots():


    # #***********************
    # # Three panel timeseries - UK, DWD, Windermere
    


    # chlorophyll = read_lake_csv(os.path.join(data_loc, "timeseries", "Windermere.csv"))
    # betula_out = read_dwd_betula(os.path.join(data_loc, "timeseries", "dwd-data_per180112_Betula_pendula_leaf_out.csv"))
    # quercus_out, quercus_fall = read_dwd_quercus(os.path.join(data_loc, "timeseries", "dwd-data_per-180112_Quercus robur leave unf.csv"))
    # betula_fall, fagus_out, fagus_fall = read_dwd_fagus(os.path.join(data_loc, "timeseries", "dwd-data_per180112_Fagus sylvatica and Betula pendula leaf data.csv"))

    # alder, chestnut, oak, beech = read_uk_csv(os.path.join(data_loc, "timeseries", "details_for_climate_report.csv"))
    # long_oak = read_uk_oak_csv(os.path.join(data_loc, "timeseries", "NatureCalendar_pedunculate_oak_first_leaf_1753_1999.csv"))

    # fig, (ax1, ax2, ax3) = plt.subplots(3, figsize=(8, 7), sharex=True)

    # # DWD data - budburst
    # utils.plot_ts_panel(ax1, [betula_out, fagus_out, quercus_out], "-", "phenological", loc="")

    # lines, labels = ax1.get_legend_handles_labels()
    # newlabels = []
    # for ll in labels:
    #     newlabels += [r'${}$'.format(ll)]
    # ax1.legend(lines, newlabels, loc="lower left", ncol=2, frameon=False, prop={'size':settings.LEGEND_FONTSIZE}, labelspacing=0.1, columnspacing=0.5)
    # ax4 = plt.axes([0.84, 0.84, 0.15, 0.15])  
    # img = mpimg.imread(os.path.join(data_loc, 'DWD_oak_leaf.jpg'))
    # ax4.imshow(img)
    # ax4.set_xticks([])
    # ax4.set_yticks([])
    

    # # UK data - budburst
    # utils.plot_ts_panel(ax2, [alder, chestnut, beech, long_oak, oak], "-", "phenological", loc="")
    # ax2.plot(long_oak.times, long_oak.data, ls=None, marker="o", c=settings.COLOURS["phenological"][long_oak.name], markeredgecolor=settings.COLOURS["phenological"][long_oak.name])
    # lines, labels = ax2.get_legend_handles_labels()
    # newlabels = []
    # for ll in labels:
    #     newlabels += [r'${}$'.format(ll)]
    # ax2.legend(lines, newlabels, loc="lower left", ncol=2, frameon=False, prop={'size':settings.LEGEND_FONTSIZE}, labelspacing=0.1, columnspacing=0.5)
    # ax5 = plt.axes([0.84, 0.54, 0.15, 0.15])  
    # img = mpimg.imread(os.path.join(data_loc, '61d1c433-b65c-47bc-b831-7e44ab74a895.jpg'))
    # ax5.imshow(img)
    # ax5.set_xticks([])
    # ax5.set_yticks([])

    # # Windermere
    # utils.plot_ts_panel(ax3, [chlorophyll], "-", "phenological", loc="lower left")
    # ax6 = plt.axes([0.84, 0.23, 0.15, 0.15])  
    # img = mpimg.imread(os.path.join(data_loc, 'Asterionella and aulacoseira 05 May 2017.jpg'))
    # ax6.imshow(img)
    # ax6.set_xticks([])
    # ax6.set_yticks([])

    # # prettify
    # ax1.set_ylim([70, 160])
    # ax2.set_ylim([70, 160])
    # ax3.set_ylim([70, 160])

    # ax2.set_ylabel("Day of year", fontsize=settings.FONTSIZE)

    # ax1.text(0.02, 0.88, "(a) Germany - tree leaf unfurling", transform=ax1.transAxes, fontsize=settings.FONTSIZE)
    # ax2.text(0.02, 0.88, "(b) UK - tree bud burst & leaf out", transform=ax2.transAxes, fontsize=settings.FONTSIZE)
    # ax3.text(0.02, 0.88, "(c) UK - Windermere - plankton", transform=ax3.transAxes, fontsize=settings.FONTSIZE)

    # for tick in ax3.xaxis.get_major_ticks():
    #     tick.label.set_fontsize(settings.FONTSIZE) 

    # minorLocator = MultipleLocator(100)
    # for ax in [ax1, ax2, ax3]:
    #     utils.thicken_panel_border(ax)
    #     ax.set_yticks(ax.get_yticks()[1:-1])
    #     ax.xaxis.set_minor_locator(minorLocator)
    #     for tick in ax.yaxis.get_major_ticks():
    #         tick.label.set_fontsize(settings.FONTSIZE) 

    # ax1.set_xlim([1950, 2020])

    # plt.setp([a.get_xticklabels() for a in [ax1, ax2]], visible=False)
    # fig.subplots_adjust(right=0.95, top=0.95, bottom=0.05, hspace=0.001)

    # plt.savefig(image_loc+"PHEN_tree_ts{}".format(settings.OUTFMT))
    # plt.close()


    # #***********************
    # # Barlett start/end timeseries - image inset
    # #   Hand-copied data from "Bartlett Gcc Transition Dates 2008-2017.xlsx"

    # # up, down, diff = read_bartlett_green(os.path.join(data_loc, "timeseries", "Bartlett_greenupdown.dat"))

    # # fig = plt.figure(figsize = (8, 9))
    # # plt.clf()

    # # # make axes by hand
    # # ax1 = plt.axes([0.15,0.3,0.8,0.65])
    # # ax2 = plt.axes([0.15,0.1,0.8,0.2], sharex = ax1)
    
    # # print "need inset axes for images"

    # # # plot data
    # # ax1.plot(up.times, up.data, c = "g", ls = "-", lw = 2, label = "Green up")
    # # ax1.plot(down.times, down.data, c = "brown", ls = "-", lw = 2, label = "Green down")
    # # ax1.fill_between(up.times, up.data, down.data, color = "0.75")

    # # ax2.plot(diff.times, diff.data, c = "c", ls = "-", lw = 2)

    # # ax1.legend(loc="upper right", ncol = 1, frameon = False, prop = {'size':settings.LEGEND_FONTSIZE}, labelspacing = 0.1, columnspacing = 0.5)

    # # # sort axes
    # # ax1.set_xlim([2008, 2018])
    # # ax2.set_ylim([140,180])
    # # ax1.text(0.02, 0.93, "(a) Bartlett seasons", transform = ax1.transAxes, fontsize = settings.FONTSIZE)
    # # ax2.text(0.02, 0.85, "(b) Difference", transform = ax2.transAxes, fontsize = settings.FONTSIZE)

    # # # prettify
    # # ax1.set_ylabel("Day of Year", fontsize = settings.FONTSIZE)
    # # ax2.set_ylabel("Days", fontsize = settings.FONTSIZE)
    # # minorLocator = MultipleLocator(100)
    # # for ax in [ax1, ax2]:
    # #     utils.thicken_panel_border(ax)
    # #     ax.set_yticks(ax.get_yticks()[1:-1])
    # #     ax.xaxis.set_minor_locator(minorLocator)
    # #     for tick in ax.yaxis.get_major_ticks():
    # #         tick.label.set_fontsize(settings.FONTSIZE) 
    # #     for tick in ax.xaxis.get_major_ticks():
    # #         tick.label.set_fontsize(settings.FONTSIZE) 

    # # plt.setp(ax1.get_xticklabels(), visible=False)

    # # plt.savefig(image_loc+"PHEN_bartlett_ts{}".format(settings.OUTFMT))
    # # plt.close()

    # #***********************
    # # Barlett start/end timeseries - image inset
    # #   Hand-copied data from "Bartlett Gcc Transition Dates 2008-2017.xlsx"
    # #   https://matplotlib.org/examples/pylab_examples/broken_axis.html

    # up, down, diff = read_bartlett_green(os.path.join(data_loc, "timeseries", "Bartlett_greenupdown.dat"))

    # fig, (ax1, ax2, ax3) = plt.subplots(3, figsize=(8, 9), sharex=True)

    # print("need inset axes for images")

    # # plot same on both
    # ax1.plot(up.times, up.data, c="g", ls="-", lw=2, label="Green up", marker="o")
    # ax1.plot(down.times, down.data, c="brown", ls="-", lw=2, label="Green down", marker="o")
    # ax1.fill_between(up.times, up.data, down.data, color="lightgreen")

    # ax2.plot(up.times, up.data, c="g", ls="-", lw=2, marker="o")
    # ax2.plot(down.times, down.data, c="brown", ls="-", lw=2, marker="o")
    # ax2.fill_between(up.times, up.data, down.data, color="lightgreen")

    # ax1.invert_yaxis()
    # ax2.invert_yaxis()

    # # hide the spines between ax and ax2
    # ax1.spines['bottom'].set_visible(False)
    # ax2.spines['top'].set_visible(False)
    # ax1.xaxis.tick_top()
    # ax1.tick_params(labeltop='off')  # don't put tick labels at the top
    # ax2.xaxis.tick_bottom()

    # # and the difference
    # ax3.plot(diff.times, diff.data, c="c", ls="-", lw=2, marker="o")

    # # plot the legend
    # ax1.legend(loc="upper right", ncol=1, frameon=False, prop={'size':settings.LEGEND_FONTSIZE}, labelspacing=0.1, columnspacing=0.5)
    
    # # prettify
    # ax1.set_xlim([2007, int(settings.YEAR)+1])
    # ax2.set_ylabel("Day of Year", fontsize=settings.FONTSIZE)
    # ax3.set_ylabel("Days", fontsize=settings.FONTSIZE)
    # ax1.text(0.02, 0.88, "(a) Bartlett seasons", transform=ax1.transAxes, fontsize=settings.FONTSIZE)
    # ax3.text(0.02, 0.85, "(b) Difference", transform=ax3.transAxes, fontsize=settings.FONTSIZE)

    # # zoom in
    # ax1.set_ylim([150, 100])
    # ax2.set_ylim([300, 250])
    # ax3.set_ylim([136, 179])

    # minorLocator = MultipleLocator(100)
    # for ax in [ax1, ax2, ax3]:
    #     utils.thicken_panel_border(ax)
    #     ax.set_yticks(ax.get_yticks()[1:-1])
    #     ax.xaxis.set_minor_locator(minorLocator)
    #     for tick in ax.yaxis.get_major_ticks():
    #         tick.label.set_fontsize(settings.FONTSIZE) 
    #     for tick in ax.xaxis.get_major_ticks():
    #         tick.label.set_fontsize(settings.FONTSIZE) 

    # plt.setp(ax1.get_xticklabels(), visible=False)
    # fig.subplots_adjust(right=0.95, top=0.95, hspace=0.001)


    # plt.savefig(image_loc+"PHEN_bartlett_ts_gap{}".format(settings.OUTFMT))
    # plt.close()

    # #***********************
    # # Bartlett GPP & Duke separate

    # fig = plt.figure(figsize=(8, 6.5))
    # plt.clf()
    # ax1 = plt.axes([0.12, 0.52, 0.78, 0.44])
    # ax2 = ax1.twinx()
    # ax3 = plt.axes([0.12, 0.08, 0.78, 0.44], sharex=ax1)
    
    # gpp, gcc = read_bartlett_gpp(os.path.join(data_loc, "timeseries", "Bartlett GPP Flux and Canopy Greenness.csv"))


    # bartlett, duke = read_bartlett_duke(os.path.join(data_loc, "timeseries", "Bartlett 2008-2017 and Duke 2017 Camera Greenness.csv"))

    # utils.plot_ts_panel(ax1, [gcc], "-", "phenological", loc="")
    # utils.plot_ts_panel(ax2, [gpp], "-", "phenological", loc="")
    # utils.plot_ts_panel(ax3, [bartlett, duke], "-", "phenological", loc="upper right", ncol=1)
    # ax3.axhline(0.36, c='0.5', ls='--')
    # ax3.axvline(185, c='0.5', ls=":")
    
    
    # # fix the legend
    # lines1, labels1 = ax1.get_legend_handles_labels()
    # lines2, labels2 = ax2.get_legend_handles_labels()
    # ax2.legend(lines1 + lines2, labels1 + labels2, loc="upper right", ncol=1, frameon=False, prop={'size':settings.LEGEND_FONTSIZE}, labelspacing=0.1, columnspacing=0.5)

    # # prettify
    # ax2.yaxis.set_label_position("right")
    # ax2.yaxis.set_ticks_position('right')

    # ax1.set_ylim([0.34, 0.48])
    # ax3.set_ylim([0.34, 0.48])
    # ax2.set_ylim([-2, 12])

    # ax1.set_ylabel("Canopy Greeness", fontsize=settings.FONTSIZE)
    # ax2.set_ylabel("Gross Primary Productivity", fontsize=settings.FONTSIZE)
    # ax3.set_ylabel("Canopy Greeness", fontsize=settings.FONTSIZE)

    # ax1.text(0.02, 0.88, "(c)", transform=ax1.transAxes, fontsize=settings.FONTSIZE)
    # ax3.text(0.02, 0.85, "(d)", transform=ax3.transAxes, fontsize=settings.FONTSIZE)

    # for tick in ax3.xaxis.get_major_ticks():
    #     tick.label.set_fontsize(settings.FONTSIZE) 

    # minorLocator = MultipleLocator(100)
    # for ax in [ax1, ax3]:
    #     utils.thicken_panel_border(ax)
    #     ax.set_yticks(ax.get_yticks()[1:-1])
    #     ax.xaxis.set_minor_locator(minorLocator)
    #     for tick in ax.yaxis.get_major_ticks():
    #         tick.label.set_fontsize(settings.FONTSIZE) 

    # utils.thicken_panel_border(ax2)
    # ax2.set_yticks(ax2.get_yticks()[1:-1])
    # for tick in ax2.yaxis.get_major_ticks():
    #     tick.label2.set_fontsize(settings.FONTSIZE)
    
    # plt.setp(ax1.get_xticklabels(), visible=False)
    # plt.setp(ax2.get_xticklabels(), visible=False)
    # fig.subplots_adjust(right=0.95, top=0.95, hspace=0.001)

    # ax4 = plt.axes([0.14, 0.65, 0.15, 0.15])  
    # img = mpimg.imread(os.path.join(data_loc, 'bbc7_2017_01_20_140005.jpg'))
    # ax4.imshow(img)
    # ax4.set_xticks([])
    # ax4.set_yticks([])
    # ax4.set_title("January")
    # ax5 = plt.axes([0.72, 0.65, 0.15, 0.15])  
    # img = mpimg.imread(os.path.join(data_loc, 'bbc7_2017_07_17_130005.jpg'))
    # ax5.imshow(img)
    # ax5.set_xticks([])
    # ax5.set_yticks([])
    # ax5.set_title("July")

    # ax6 = plt.axes([0.14, 0.25, 0.15, 0.15])  
    # img = mpimg.imread(os.path.join(data_loc, 'bbc7_2017_07_04_124505.jpg'))
    # ax6.imshow(img)
    # ax6.set_xticks([])
    # ax6.set_yticks([])
    # ax6.set_title("Bartlett")
    # ax7 = plt.axes([0.72, 0.25, 0.15, 0.15])  
    # img = mpimg.imread(os.path.join(data_loc, 'dukehw_2017_07_04_120110.jpg'))
    # ax7.imshow(img)
    # ax7.set_xticks([])
    # ax7.set_yticks([])
    # ax7.set_title("Duke")


    # plt.savefig(image_loc+"PHEN_Bartlett_GPP_Duke_separate{}".format(settings.OUTFMT))
    # plt.close()

    # #***********************
    # # Bartlett GPP & Duke combined

    # # fig = plt.figure(figsize = (8, 5))
    # # plt.clf()
    # # ax1 = plt.axes([0.12, 0.1, 0.78, 0.8])
    # # ax2 = ax1.twinx()
    
    # # gpp, gcc = read_bartlett_gpp(os.path.join(data_loc, "timeseries", "Bartlett GPP Flux and Canopy Greenness.csv"))

    # # bartlett, duke = read_bartlett_duke(os.path.join(data_loc, "timeseries", "Bartlett 2008-2017 and Duke 2017 Camera Greenness.csv"))

    # # utils.plot_ts_panel(ax1, [gcc, duke], "-", "phenological", loc = "")
    # # utils.plot_ts_panel(ax2, [gpp], "-", "phenological", loc = "")
    
    # # # fix the legend
    # # lines1, labels1 = ax1.get_legend_handles_labels()
    # # lines2, labels2 = ax2.get_legend_handles_labels()
    # # # have to remove duplicate label
    # # ax2.legend(lines1 + lines2, labels1 + labels2, loc="upper right", ncol = 1, frameon = False, prop = {'size':settings.LEGEND_FONTSIZE}, labelspacing = 0.1, columnspacing = 0.5)

    # # # prettify
    # # ax2.yaxis.set_label_position("right")

    # # ax1.set_ylim([0.34, 0.48])
    # # ax2.set_ylim([-2, 12])

    # # ax1.set_ylabel("Canopy Greeness", fontsize = settings.FONTSIZE)
    # # ax2.set_ylabel("Gross Primary Productivity", fontsize = settings.FONTSIZE)
 
    # # for tick in ax1.xaxis.get_major_ticks():
    # #     tick.label.set_fontsize(settings.FONTSIZE) 

    # # minorLocator = MultipleLocator(100)
    # # for ax in [ax1, ax3]:
    # #     utils.thicken_panel_border(ax)
    # #     ax.set_yticks(ax.get_yticks()[1:])
    # #     ax.xaxis.set_minor_locator(minorLocator)
    # #     for tick in ax.yaxis.get_major_ticks():
    # #         tick.label.set_fontsize(settings.FONTSIZE) 

    # # utils.thicken_panel_border(ax2)
    # # ax2.set_yticks(ax2.get_yticks()[1:-1])
    # # for tick in ax2.yaxis.get_major_ticks():
    # #     tick.label2.set_fontsize(settings.FONTSIZE)
    
    # # fig.subplots_adjust(right = 0.95, top = 0.95, hspace = 0.001)

    # # plt.savefig(image_loc+"PHEN_Bartlett_GPP_Duke_combined{}".format(settings.OUTFMT))
    # # plt.close()

    # #***********************
    # # UK Map
    # import cartopy.feature as cfeature
    # land_50m = cfeature.NaturalEarthFeature('physical', 'land', '50m',
    #                                         edgecolor='face',
    #                                         facecolor=cfeature.COLORS['land'])
 
    # species, days, lats, lons = read_uk_map_csv(os.path.join(data_loc, "timeseries", "UK_Leafout_4Trees.csv"))
    
    # cmap = plt.cm.YlGn
    # bounds = np.arange(80, 160, 10)
    # norm = mpl.cm.colors.BoundaryNorm(bounds, cmap.N)

    # fig = plt.figure(figsize=(8, 10.5))
    # plt.clf()
    # ax = plt.axes([0.05, 0.05, 0.9, 0.9], projection=cartopy.crs.LambertConformal(central_longitude=-7.5))

    # ax.gridlines() #draw_labels=True)
    # ax.add_feature(land_50m, zorder=0, facecolor="0.9", edgecolor="k")
    # ax.set_extent([-10, 4, 48, 60], cartopy.crs.PlateCarree())

    # scat = ax.scatter(lons, lats, c=days, transform=cartopy.crs.PlateCarree(), cmap=cmap, norm=norm, s=25, edgecolor='0.5', linewidth='0.5', zorder=10)

    # utils.thicken_panel_border(ax)

    # cb = plt.colorbar(scat, orientation='horizontal', ticks=bounds[1:-1], label="Day of year", drawedges=True, fraction=0.1, pad=0.05, aspect=15, shrink=0.8)

    # # prettify
    # cb.set_ticklabels(["{:g}".format(b) for b in bounds[1:-1]])
    # cb.outline.set_linewidth(2)
    # cb.dividers.set_color('k')
    # cb.dividers.set_linewidth(2)

    # plt.savefig(image_loc + "PHEN_UK_map{}".format(settings.OUTFMT))
    # plt.close()


    #***********************
    # MODIS

    cubelist = iris.load(os.path.join(data_loc, "MODIS.CMG.{}.SOS.EOS.Anomaly.nc".format(settings.YEAR)))

    for c, cube in enumerate(cubelist):
        if cube.name() == "EOS":
            eos_cube = cubelist[c]
        elif cube.name() == "SOS":
            sos_cube = cubelist[c]
        elif cube.name() == "MAX":
            max_cube = cubelist[c]
       
    # deal with NANS
#    eos_cube.data = np.ma.masked_where(eos_cube.data != eos_cube.data, eos_cube.data)
    sos_cube.data = np.ma.masked_where(sos_cube.data != sos_cube.data, sos_cube.data)
#    max_cube.data = np.ma.masked_where(max_cube.data != max_cube.data, max_cube.data)


            
    # set up a 1 x 2 set of axes (2018 only needs one panel)
    fig = plt.figure(figsize=(8, 8))
    plt.clf()

    # set up plot settings
    BOUNDS = [[-100, -20, -10, -5, -2, 0, 2, 5, 10, 20, 100]]#, [-100, -20, -10, -5, -2, 0, 2, 5, 10, 20, 100]]
    CMAPS = [settings.COLOURMAP_DICT["phenological_r"]]#, settings.COLOURMAP_DICT["phenological"]]

    CUBES = [sos_cube]# eos_cube]
    LABELS = ["(a) Start of Season (SOS)"]#, "(b) End of Season (EOS)"]

    # boundary circle
    theta = np.linspace(0, 2*np.pi, 100)
    center, radius = [0.5, 0.5], 0.5
    verts = np.vstack([np.sin(theta), np.cos(theta)]).T
    circle = mpath.Path(verts * radius + center)

    # spin through axes
    for a in range(1):  

        ax = plt.subplot(1, 1, a+1, projection=cartopy.crs.NorthPolarStereo())

        plot_cube = CUBES[a]

        if settings.OUTFMT in [".eps", ".pdf"]:
            if plot_cube.coord("latitude").points.shape[0] > 90 or plot_cube.coord("longitude").points.shape[0] > 360:
                regrid_size = 1.0
                print("Regridding cube for {} output to {} degree resolution".format(settings.OUTFMT, regrid_size))
                print("Old Shape {}".format(plot_cube.data.shape))
                plot_cube = utils.regrid_cube(plot_cube, regrid_size, regrid_size)
                print("New Shape {}".format(plot_cube.data.shape))

        ax.gridlines() #draw_labels=True)
        ax.add_feature(cartopy.feature.LAND, zorder=0, facecolor="0.9", edgecolor="k")
        ax.coastlines()
        ax.set_boundary(circle, transform=ax.transAxes)
        ax.set_extent([-180, 180, 45, 90], cartopy.crs.PlateCarree())

        ext = ax.get_extent() # save the original extent

        cmap = CMAPS[a]
        norm = mpl.cm.colors.BoundaryNorm(BOUNDS[a], cmap.N)
        mesh = iris.plot.pcolormesh(plot_cube, cmap=cmap, norm=norm, axes=ax)

        ax.set_extent(ext, ax.projection) # fix the extent change from colormesh
        ax.text(-0.1, 1.0, LABELS[a], fontsize=settings.FONTSIZE * 0.8, transform=ax.transAxes)

        cb = plt.colorbar(mesh, orientation='horizontal', ticks=BOUNDS[a][1:-1], label="Anomaly (days)", drawedges=True, fraction=0.1, pad=0.05, aspect=15, shrink=0.8)
        # prettify
        cb.set_ticklabels(["{:g}".format(b) for b in BOUNDS[a][1:-1]])
        cb.outline.set_linewidth(2)
        cb.dividers.set_color('k')
        cb.dividers.set_linewidth(2)

        ax.set_extent([-180, 180, 45, 90], cartopy.crs.PlateCarree())

    fig.subplots_adjust(bottom=0.05, top=0.95, left=0.04, right=0.95, wspace=0.02)

    plt.title("")

    plt.savefig(image_loc + "PHEN_modis_polar{}".format(settings.OUTFMT))
    plt.close()

    del eos_cube
    del sos_cube
    del cubelist

    #***********************
    # MODIS LAI
    # max_cube.data = np.ma.masked_where(max_cube.data <= -9000, max_cube.data)
    # if settings.OUTFMT in [".eps", ".pdf"]:
    #     if max_cube.coord("latitude").points.shape[0] > 180 or max_cube.coord("longitude").points.shape[0] > 360:
    #         regrid_size = 1.0
    #         print("Regridding cube for {} output to {} degree resolution".format(settings.OUTFMT, regrid_size))
    #         print("Old Shape {}".format(max_cube.data.shape))
    #         max_cube = utils.regrid_cube(max_cube, regrid_size, regrid_size)
    #         print("New Shape {}".format(max_cube.data.shape))

    # fig = plt.figure(figsize=(8, 8))
    # plt.clf()
    # ax = plt.axes([0.05, 0.05, 0.9, 0.9], projection=cartopy.crs.NorthPolarStereo())

    # ax.gridlines() #draw_labels=True)
    # ax.add_feature(cartopy.feature.LAND, zorder=0, facecolor="0.9", edgecolor="k")
    # ax.coastlines()
    # ax.set_boundary(circle, transform=ax.transAxes)
    # ax.set_extent([-180, 180, 45, 90], cartopy.crs.PlateCarree())

    # ext = ax.get_extent() # save the original extent

    # cmap = settings.COLOURMAP_DICT["phenological_r"]
    # bounds = [-100, -5, -3, -2, -1, 0, 1, 2, 3, 5, 100]
    # norm = mpl.cm.colors.BoundaryNorm(bounds, cmap.N)
    # mesh = iris.plot.pcolormesh(max_cube, cmap=cmap, norm=norm, axes=ax)

    # ax.set_extent(ext, ax.projection) # fix the extent change from colormesh
    # ax.text(-0.1, 1.0, "Max Leaf Area Index", fontsize=settings.FONTSIZE * 0.8, transform=ax.transAxes)

    # cb = plt.colorbar(mesh, orientation='horizontal', ticks=bounds[1:-1], label="Anomaly (m"+r'$^2'+"/m"+r'$^2'+")", drawedges=True, fraction=0.1, pad=0.05, aspect=15, shrink=0.8)
    # # prettify
    # cb.set_ticklabels(["{:g}".format(b) for b in bounds[1:-1]])
    # cb.outline.set_linewidth(2)
    # cb.dividers.set_color('k')
    # cb.dividers.set_linewidth(2)

    # ax.set_extent([-180, 180, 45, 90], cartopy.crs.PlateCarree())

    # plt.savefig(image_loc + "PHEN_modis_lai{}".format(settings.OUTFMT))
    # plt.close()

    #***********************
    # MODIS timeseries - 2017

    # sos, eos, lai = read_modis_ts(os.path.join(data_loc, "MODIS.CMG.{}.SOS.EOS.MAX.AnomalyTS.csv".format(settings.YEAR)))


    # plt.clf()

    # fig, (ax1, ax2) = plt.subplots(2, figsize=(8, 4), sharex=True)
    
    # # plot same on both
    # ax1.plot(sos.times, sos.data, c="g", ls="-", lw=2, label="Start of Season", marker="o")
    # ax1.plot(eos.times, eos.data, c="brown", ls="-", lw=2, label="End of Season", marker="o")
    # ax1.fill_between(eos.times, eos.data, sos.data, color="lightgreen")

    # ax2.plot(sos.times, sos.data, c="g", ls="-", lw=2, marker="o")
    # ax2.plot(eos.times, eos.data, c="brown", ls="-", lw=2, marker="o")
    # ax2.fill_between(eos.times, eos.data, sos.data, color="lightgreen")

    # # invert so green down is on the bottom
    # ax1.invert_yaxis()
    # ax2.invert_yaxis()

    # # hide the spines between ax and ax2
    # ax1.spines['bottom'].set_visible(False)
    # ax2.spines['top'].set_visible(False)
    # ax1.xaxis.tick_top()
    # ax1.tick_params(labeltop='off')  # don't put tick labels at the top
    # ax2.xaxis.tick_bottom()

    # # plot the legend
    # ax1.legend(loc="upper right", ncol=1, frameon=False, prop={'size':settings.LEGEND_FONTSIZE}, labelspacing=0.1, columnspacing=0.5)
    
    # # prettify
    # ax1.set_xlim([1999, 2018])
    # ax2.set_ylabel("Day of Year", fontsize=settings.FONTSIZE)

    # # zoom in
    # ax1.set_ylim([160, 110])
    # ax2.set_ylim([300, 250])

    # # set label
    # ax1.text(-0.1, 0.92, "(c)", transform=ax1.transAxes, fontsize=settings.FONTSIZE)

    # minorLocator = MultipleLocator(100)
    # for ax in [ax1, ax2]:
    #     utils.thicken_panel_border(ax)
    #     ax.set_yticks(ax.get_yticks()[1:-1])
    #     ax.xaxis.set_minor_locator(minorLocator)
    #     for tick in ax.yaxis.get_major_ticks():
    #         tick.label.set_fontsize(settings.FONTSIZE) 
    #     for tick in ax.xaxis.get_major_ticks():
    #         tick.label.set_fontsize(settings.FONTSIZE) 

    # plt.setp(ax1.get_xticklabels(), visible=False)
    # fig.subplots_adjust(right=0.95, top=0.95, hspace=0.001)

    # plt.savefig(image_loc+"PHEN_modis_ts{}".format(settings.OUTFMT))
    # plt.close()

    #***********************
    # MODIS timeseries - 2018
    
    sos_na, sos_ea, sprt_na, sprt_ea = read_modis_ts(os.path.join(data_loc, "MODIS.CMG.{}.SOS.EOS.SPRT.FALT.TS.csv".format(settings.YEAR)))

    dummy, sos_na = utils.calculate_climatology_and_anomalies_1d(sos_na, 2000, 2010)
    dummy, sos_ea = utils.calculate_climatology_and_anomalies_1d(sos_ea, 2000, 2010)

    fig, (ax1, ax2) = plt.subplots(2, figsize=(8, 6.5), sharex=True)

    # North America
    # use un-anomalised spring T to get legend without the data
    utils.plot_ts_panel(ax1, [sos_na, sprt_na], "-", "phenological", loc=LEGEND_LOC)   

    # Eurasia
    utils.plot_ts_panel(ax2, [sos_ea, sprt_ea], "-", "phenological", loc=LEGEND_LOC)

    # make twin axes for Spring T
    dummy, sprt_na = utils.calculate_climatology_and_anomalies_1d(sprt_na, 2000, 2010)
    dummy, sprt_ea = utils.calculate_climatology_and_anomalies_1d(sprt_ea, 2000, 2010)

    ax3 = ax1.twinx()
    utils.plot_ts_panel(ax3, [sprt_na], "-", "phenological", loc="")   

    ax4 = ax2.twinx()
    utils.plot_ts_panel(ax4, [sprt_ea], "-", "phenological", loc="")   

    # prettify
    ax1.set_ylim([-8, 8])
    ax2.set_ylim([-8, 8])
    ax3.set_ylim([2, -2])
    ax4.set_ylim([2, -2])

    # labels
    ax1.text(0.02, 0.88, "(a) North America", transform=ax1.transAxes, fontsize=settings.FONTSIZE)
    ax2.text(0.02, 0.88, "(b) Eurasia", transform=ax2.transAxes, fontsize=settings.FONTSIZE)

    ax1.text(0.47, 0.88, "2018 SOS Anomaly = 1.86 days", transform=ax1.transAxes, fontsize=settings.FONTSIZE*0.8)
    ax1.text(0.47, 0.78, "2018 Spring T anomaly = -0.75 "+r'$^{\circ}$'+"C", transform=ax1.transAxes, fontsize=settings.FONTSIZE*0.8)
    ax2.text(0.47, 0.88, "2018 SOS Anomaly = 2.01 days", transform=ax2.transAxes, fontsize=settings.FONTSIZE*0.8)
    ax2.text(0.47, 0.78, "2018 Spring T anomaly = 0.13 "+r'$^{\circ}$'+"C", transform=ax2.transAxes, fontsize=settings.FONTSIZE*0.8)

    fig.text(0.01, 0.5, "SOS Anomaly (days)", va='center', rotation='vertical', fontsize = settings.FONTSIZE)
    fig.text(0.95, 0.5, "Temperature Anomaly ("+r'$^{\circ}$'+"C)", va='center', rotation='vertical', fontsize = settings.FONTSIZE)

    # ticks and labels
    for tick in ax2.xaxis.get_major_ticks():
        tick.label.set_fontsize(settings.FONTSIZE) 

    minorLocator = MultipleLocator(1)
    for ax in [ax1, ax2]:
        utils.thicken_panel_border(ax)
        ax.set_yticks(ax.get_yticks()[1:-1])
        ax.xaxis.set_minor_locator(minorLocator)
        for tick in ax.yaxis.get_major_ticks():
            tick.label.set_fontsize(settings.FONTSIZE) 

    for ax in [ax3, ax4]:
        ax.yaxis.tick_right()
        utils.thicken_panel_border(ax)
        ax.set_yticks(ax.get_yticks()[1:-1])
        ax.xaxis.set_minor_locator(minorLocator)
        for tick in ax.yaxis.get_major_ticks():
            tick.label2.set_fontsize(settings.FONTSIZE) 

    # final settings
    ax1.set_xlim([1999, 2020])

    plt.setp([a.get_xticklabels() for a in [ax1]], visible=False)
    fig.subplots_adjust(left=0.1, right=0.85, top=0.95, bottom=0.05, hspace=0.001)

    plt.savefig(image_loc+"PHEN_modis_ts{}".format(settings.OUTFMT))
    plt.close()



    return # run_all_plots