示例#1
0
def draw_gh_uv_mslp(gh=None,
                    uv=None,
                    mslp=None,
                    map_extent=(50, 150, 0, 65),
                    regrid_shape=20,
                    add_china=True,
                    city=True,
                    south_China_sea=True,
                    output_dir=None,
                    Global=False):

    plt.rcParams['font.sans-serif'] = ['SimHei']  # 步骤一(替换sans-serif字体)
    plt.rcParams['axes.unicode_minus'] = False  # 步骤二(解决坐标轴负数的负号显示问题)

    # draw figure
    plt.figure(figsize=(16, 9))

    # set data projection
    if (Global == True):
        plotcrs = ccrs.Robinson(central_longitude=115.)
    else:
        plotcrs = ccrs.AlbersEqualArea(
            central_latitude=(map_extent[2] + map_extent[3]) / 2.,
            central_longitude=(map_extent[0] + map_extent[1]) / 2.,
            standard_parallels=[30., 60.])

    ax = plt.axes([0.01, 0.1, .98, .84], projection=plotcrs)

    plt.title('[' + gh.attrs['model'] + '] ' +
              str(int(gh['level'].values[0])) + 'hPa 位势高度场, ' +
              str(int(uv['level'].values[0])) + 'hPa 风场, 海平面气压场',
              loc='left',
              fontsize=30)

    datacrs = ccrs.PlateCarree()

    #adapt to the map ratio
    map_extent2 = utl.adjust_map_ratio(ax,
                                       map_extent=map_extent,
                                       datacrs=datacrs)
    #adapt to the map ratio

    ax.add_feature(cfeature.OCEAN)
    utl.add_china_map_2cartopy_public(ax,
                                      name='coastline',
                                      edgecolor='gray',
                                      lw=0.8,
                                      zorder=5,
                                      alpha=0.5)
    if add_china:
        utl.add_china_map_2cartopy_public(ax,
                                          name='province',
                                          edgecolor='gray',
                                          lw=0.5,
                                          zorder=5)
        utl.add_china_map_2cartopy_public(ax,
                                          name='nation',
                                          edgecolor='black',
                                          lw=0.8,
                                          zorder=5)
        utl.add_china_map_2cartopy_public(ax,
                                          name='river',
                                          edgecolor='#74b9ff',
                                          lw=0.8,
                                          zorder=5,
                                          alpha=0.5)

    # define return plots
    plots = {}
    # draw mean sea level pressure
    if mslp is not None:
        x, y = np.meshgrid(mslp['lon'], mslp['lat'])
        clevs_mslp = np.arange(960, 1065, 5)
        cmap = guide_cmaps(26)
        plots['mslp'] = ax.contourf(x,
                                    y,
                                    np.squeeze(mslp['data']),
                                    clevs_mslp,
                                    cmap=cmap,
                                    alpha=0.8,
                                    zorder=1,
                                    transform=datacrs)
        #+画高低压中心
        res = mslp['lon'].values[1] - mslp['lon'].values[0]
        nwindow = int(9.5 / res)
        mslp_hl = np.ma.masked_invalid(mslp['data'].values).squeeze()
        local_min, local_max = utl.extrema(mslp_hl,
                                           mode='wrap',
                                           window=nwindow)
        #Get location of extrema on grid
        xmin, xmax, ymin, ymax = map_extent2
        lons2d, lats2d = x, y
        transformed = datacrs.transform_points(datacrs, lons2d, lats2d)
        x = transformed[..., 0]
        y = transformed[..., 1]
        xlows = x[local_min]
        xhighs = x[local_max]
        ylows = y[local_min]
        yhighs = y[local_max]
        lowvals = mslp_hl[local_min]
        highvals = mslp_hl[local_max]
        yoffset = 0.022 * (ymax - ymin)
        dmin = yoffset
        #Plot low pressures
        xyplotted = []
        for x, y, p in zip(xlows, ylows, lowvals):
            if x < xmax - yoffset and x > xmin + yoffset and y < ymax - yoffset and y > ymin + yoffset:
                dist = [
                    np.sqrt((x - x0)**2 + (y - y0)**2) for x0, y0 in xyplotted
                ]
                if not dist or min(dist) > dmin:  #,fontweight='bold'
                    a = ax.text(x,
                                y,
                                'L',
                                fontsize=28,
                                ha='center',
                                va='center',
                                color='r',
                                fontweight='normal',
                                transform=datacrs)
                    b = ax.text(x,
                                y - yoffset,
                                repr(int(p)),
                                fontsize=14,
                                ha='center',
                                va='top',
                                color='r',
                                fontweight='normal',
                                transform=datacrs)
                    a.set_path_effects([
                        path_effects.Stroke(linewidth=1.5, foreground='black'),
                        path_effects.SimpleLineShadow(),
                        path_effects.Normal()
                    ])
                    b.set_path_effects([
                        path_effects.Stroke(linewidth=1.0, foreground='black'),
                        path_effects.SimpleLineShadow(),
                        path_effects.Normal()
                    ])
                    xyplotted.append((x, y))

        #Plot high pressures
        xyplotted = []
        for x, y, p in zip(xhighs, yhighs, highvals):
            if x < xmax - yoffset and x > xmin + yoffset and y < ymax - yoffset and y > ymin + yoffset:
                dist = [
                    np.sqrt((x - x0)**2 + (y - y0)**2) for x0, y0 in xyplotted
                ]
                if not dist or min(dist) > dmin:
                    a = ax.text(x,
                                y,
                                'H',
                                fontsize=28,
                                ha='center',
                                va='center',
                                color='b',
                                fontweight='normal',
                                transform=datacrs)
                    b = ax.text(x,
                                y - yoffset,
                                repr(int(p)),
                                fontsize=14,
                                ha='center',
                                va='top',
                                color='b',
                                fontweight='normal',
                                transform=datacrs)
                    a.set_path_effects([
                        path_effects.Stroke(linewidth=1.5, foreground='black'),
                        path_effects.SimpleLineShadow(),
                        path_effects.Normal()
                    ])
                    b.set_path_effects([
                        path_effects.Stroke(linewidth=1.0, foreground='black'),
                        path_effects.SimpleLineShadow(),
                        path_effects.Normal()
                    ])
                    xyplotted.append((x, y))
        #-画高低压中心

    # draw -hPa wind bards
    if uv is not None:
        x, y = np.meshgrid(uv['lon'], uv['lat'])
        u = np.squeeze(uv['u']) * 2.5
        v = np.squeeze(uv['v']) * 2.5
        plots['uv'] = ax.barbs(x,
                               y,
                               u.values,
                               v.values,
                               length=6,
                               regrid_shape=regrid_shape,
                               transform=datacrs,
                               fill_empty=False,
                               sizes=dict(emptybarb=0.05),
                               zorder=2)

    # draw -hPa geopotential height
    if gh is not None:
        x, y = np.meshgrid(gh['lon'], gh['lat'])
        clevs_gh = np.append(
            np.append(
                np.arange(0, 480, 4),
                np.append(np.arange(480, 584, 8), np.arange(580, 604, 4))),
            np.arange(604, 2000, 8))
        linewidths_gh = np.zeros(clevs_gh.shape) + 2
        idx_588 = np.where(clevs_gh == 588)
        linewidths_gh[idx_588[0]] = 4
        plots['gh'] = ax.contour(x,
                                 y,
                                 np.squeeze(gh['data']),
                                 clevs_gh,
                                 colors='purple',
                                 linewidths=linewidths_gh,
                                 transform=datacrs,
                                 zorder=3)
        ax.clabel(plots['gh'],
                  inline=1,
                  fontsize=20,
                  fmt='%.0f',
                  colors='black')

    # grid lines
    gl = ax.gridlines(crs=datacrs,
                      linewidth=2,
                      color='gray',
                      alpha=0.5,
                      linestyle='--',
                      zorder=4)
    gl.xlocator = mpl.ticker.FixedLocator(np.arange(0, 360, 15))
    gl.ylocator = mpl.ticker.FixedLocator(np.arange(-90, 90, 15))

    utl.add_cartopy_background(ax, name='RD')
    #forecast information
    l, b, w, h = ax.get_position().bounds

    bax = plt.axes([l, b + h - 0.1, .25, .1], facecolor='#FFFFFFCC')
    bax.set_yticks([])
    bax.set_xticks([])
    bax.axis([0, 10, 0, 10])

    initTime = pd.to_datetime(str(
        gh.coords['forecast_reference_time'].values)).replace(
            tzinfo=None).to_pydatetime()
    fcst_time = initTime + timedelta(
        hours=gh.coords['forecast_period'].values[0])
    #发布时间
    if (sys.platform[0:3] == 'lin'):
        locale.setlocale(locale.LC_CTYPE, 'zh_CN.utf8')
    if (sys.platform[0:3] == 'win'):
        locale.setlocale(locale.LC_CTYPE, 'chinese')
    plt.text(2.5, 7.5, '起报时间: ' + initTime.strftime("%Y年%m月%d日%H时"), size=15)
    plt.text(2.5, 5, '预报时间: ' + fcst_time.strftime("%Y年%m月%d日%H时"), size=15)
    plt.text(2.5,
             2.5,
             '预报时效: ' + str(int(gh.coords['forecast_period'].values[0])) +
             '小时',
             size=15)
    plt.text(2.5, 0.5, 'www.nmc.cn', size=15)

    # add color bar
    cax = plt.axes([l, b - 0.04, w, .02])
    cb = plt.colorbar(plots['mslp'],
                      cax=cax,
                      orientation='horizontal',
                      ticks=clevs_mslp[:-1],
                      extend='max',
                      extendrect=False)
    cb.ax.tick_params(labelsize='x-large')
    cb.set_label('Mean sea level pressure (hPa)', size=20)

    # add south China sea
    if south_China_sea:
        utl.add_south_China_sea(pos=[l + w - 0.091, b, .1, .2])

    small_city = False
    if (map_extent2[1] - map_extent2[0] < 25):
        small_city = True
    if city:
        utl.add_city_on_map(ax,
                            map_extent=map_extent2,
                            transform=datacrs,
                            zorder=6,
                            size=15,
                            small_city=small_city)

    utl.add_logo_extra_in_axes(pos=[l - 0.02, b + h - 0.1, .1, .1],
                               which='nmc',
                               size='Xlarge')
    # show figure
    if (output_dir != None):
        plt.savefig(output_dir + '最高温度_预报_' + '起报时间_' +
                    initTime.strftime("%Y年%m月%d日%H时") + '预报时效_' +
                    str(gh.coords['forecast_period'].values[0]) + '小时' +
                    '.png',
                    dpi=200,
                    bbox_inches='tight')

    if (output_dir == None):
        plt.show()
def draw_gh_uv_mslp(gh=None,
                    uv=None,
                    mslp=None,
                    map_extent=(50, 150, 0, 65),
                    regrid_shape=20,
                    add_china=True,
                    city=True,
                    south_China_sea=True,
                    output_dir=None,
                    Global=False):

    plt.rcParams['font.sans-serif'] = ['SimHei']  # 步骤一(替换sans-serif字体)
    plt.rcParams['axes.unicode_minus'] = False  # 步骤二(解决坐标轴负数的负号显示问题)

    # draw figure
    plt.figure(figsize=(16, 9))

    # set data projection
    if (Global == True):
        plotcrs = ccrs.Robinson(central_longitude=115.)
    else:
        plotcrs = ccrs.AlbersEqualArea(
            central_latitude=(map_extent[2] + map_extent[3]) / 2.,
            central_longitude=(map_extent[0] + map_extent[1]) / 2.,
            standard_parallels=[30., 60.])

    ax = plt.axes([0.01, 0.1, .98, .84], projection=plotcrs)

    plt.title('[' + gh.attrs['model'] + '] ' +
              str(int(gh['level'].values[0])) + 'hPa 位势高度场, ' +
              str(int(uv['level'].values[0])) + 'hPa 风场, 海平面气压场',
              loc='left',
              fontsize=30)

    datacrs = ccrs.PlateCarree()

    #adapt to the map ratio
    map_extent2 = utl.adjust_map_ratio(ax,
                                       map_extent=map_extent,
                                       datacrs=datacrs)
    #adapt to the map ratio

    ax.add_feature(cfeature.OCEAN)
    utl.add_china_map_2cartopy_public(ax,
                                      name='coastline',
                                      edgecolor='gray',
                                      lw=0.8,
                                      zorder=5,
                                      alpha=0.5)
    if add_china:
        utl.add_china_map_2cartopy_public(ax,
                                          name='province',
                                          edgecolor='gray',
                                          lw=0.5,
                                          zorder=5)
        utl.add_china_map_2cartopy_public(ax,
                                          name='nation',
                                          edgecolor='black',
                                          lw=0.8,
                                          zorder=5)
        utl.add_china_map_2cartopy_public(ax,
                                          name='river',
                                          edgecolor='#74b9ff',
                                          lw=0.8,
                                          zorder=5,
                                          alpha=0.5)

    # define return plots
    plots = {}
    # draw mean sea level pressure
    if mslp is not None:
        x, y = np.meshgrid(mslp['lon'], mslp['lat'])
        clevs_mslp = np.arange(960, 1065, 5)
        cmap = guide_cmaps(26)
        plots['mslp'] = ax.contourf(x,
                                    y,
                                    np.squeeze(mslp['data']),
                                    clevs_mslp,
                                    cmap=cmap,
                                    alpha=0.8,
                                    zorder=1,
                                    transform=datacrs)

    # draw -hPa wind bards
    if uv is not None:
        x, y = np.meshgrid(uv['lon'], uv['lat'])
        u = np.squeeze(uv['u']) * 2.5
        v = np.squeeze(uv['v']) * 2.5
        plots['uv'] = ax.barbs(x,
                               y,
                               u.values,
                               v.values,
                               length=6,
                               regrid_shape=regrid_shape,
                               transform=datacrs,
                               fill_empty=False,
                               sizes=dict(emptybarb=0.05),
                               zorder=2)

    # draw -hPa geopotential height
    if gh is not None:
        x, y = np.meshgrid(gh['lon'], gh['lat'])
        clevs_gh = np.append(
            np.append(
                np.arange(0, 480, 4),
                np.append(np.arange(480, 584, 8), np.arange(580, 604, 4))),
            np.arange(604, 2000, 8))
        plots['gh'] = ax.contour(x,
                                 y,
                                 np.squeeze(gh['data']),
                                 clevs_gh,
                                 colors='purple',
                                 linewidths=2,
                                 transform=datacrs,
                                 zorder=3)
        ax.clabel(plots['gh'],
                  inline=1,
                  fontsize=20,
                  fmt='%.0f',
                  colors='black')

    # grid lines
    gl = ax.gridlines(crs=datacrs,
                      linewidth=2,
                      color='gray',
                      alpha=0.5,
                      linestyle='--',
                      zorder=4)
    gl.xlocator = mpl.ticker.FixedLocator(np.arange(0, 360, 15))
    gl.ylocator = mpl.ticker.FixedLocator(np.arange(-90, 90, 15))

    utl.add_cartopy_background(ax, name='RD')
    #forecast information
    l, b, w, h = ax.get_position().bounds

    bax = plt.axes([l, b + h - 0.1, .25, .1], facecolor='#FFFFFFCC')
    bax.set_yticks([])
    bax.set_xticks([])
    bax.axis([0, 10, 0, 10])

    initTime = pd.to_datetime(str(
        gh.coords['forecast_reference_time'].values)).replace(
            tzinfo=None).to_pydatetime()
    fcst_time = initTime + timedelta(
        hours=gh.coords['forecast_period'].values[0])
    #发布时间
    if (sys.platform[0:3] == 'lin'):
        locale.setlocale(locale.LC_CTYPE, 'zh_CN.utf8')
    if (sys.platform[0:3] == 'win'):
        locale.setlocale(locale.LC_CTYPE, 'chinese')
    plt.text(2.5, 7.5, '起报时间: ' + initTime.strftime("%Y年%m月%d日%H时"), size=15)
    plt.text(2.5, 5, '预报时间: ' + fcst_time.strftime("%Y年%m月%d日%H时"), size=15)
    plt.text(2.5,
             2.5,
             '预报时效: ' + str(int(gh.coords['forecast_period'].values[0])) +
             '小时',
             size=15)
    plt.text(2.5, 0.5, 'www.nmc.cn', size=15)

    # add color bar
    cax = plt.axes([l, b - 0.04, w, .02])
    cb = plt.colorbar(plots['mslp'],
                      cax=cax,
                      orientation='horizontal',
                      ticks=clevs_mslp[:-1],
                      extend='max',
                      extendrect=False)
    cb.ax.tick_params(labelsize='x-large')
    cb.set_label('Mean sea level pressure (hPa)', size=20)

    # add south China sea
    if south_China_sea:
        utl.add_south_China_sea(pos=[l + w - 0.091, b, .1, .2])

    small_city = False
    if (map_extent2[1] - map_extent2[0] < 25):
        small_city = True
    if city:
        utl.add_city_on_map(ax,
                            map_extent=map_extent2,
                            transform=datacrs,
                            zorder=6,
                            size=15,
                            small_city=small_city)

    utl.add_logo_extra_in_axes(pos=[l - 0.02, b + h - 0.1, .1, .1],
                               which='nmc',
                               size='Xlarge')
    # show figure
    if (output_dir != None):
        plt.savefig(output_dir + '最高温度_预报_' + '起报时间_' +
                    initTime.strftime("%Y年%m月%d日%H时") + '预报时效_' +
                    str(gh.coords['forecast_period'].values[0]) + '小时' +
                    '.png',
                    dpi=200,
                    bbox_inches='tight')

    if (output_dir == None):
        plt.show()
示例#3
0
def get_plot_attrs(name, clevs=None, min_lev=None, extend='max'):
    """
    获得预先设置的各种变量绘图属性.

    Args:
        name (str): the name of predefined plot attributes.

    Returns:
        dict: plot attribute dictionary.
    """

    # convert to lower
    name = name.lower()

    if name == 'z_500_contour':
        if clevs is None:
            clevs = np.concatenate((np.arange(480, 580,
                                              4), np.arange(580, 604, 4)))
        clevs = np.asarray(clevs)
        linewidths = np.full(len(clevs), 1)
        linewidths[clevs == 588] = 2
        return {"levels": clevs, "linewidths": linewidths}

    elif name == 'qpf_1h_contourf_blues':
        if clevs is None:
            clevs = [0.1, 4, 13, 25, 60, 120, 250]
        clevs = np.asarray(clevs)
        cmap = cm.truncate_colormap('Blues', minval=0.1)
        norm = mpl.colors.BoundaryNorm(clevs, cmap.N, extend=extend)
        return {'clevs': clevs, 'cmap': cmap, 'norm': norm}

    elif name == 'nmc_accumulated_rainfall':
        if clevs is None:
            clevs = [0.1, 10, 25, 50, 100, 250, 400, 600, 800, 1000]
        clevs = np.asarray(clevs)
        _colors = [[161, 241, 141], [61, 186, 61], [96, 184, 255], [0, 0, 255],
                   [250, 0, 250], [128, 0, 64], [255, 170, 0], [255, 102, 0],
                   [230, 0, 0], [80, 45, 10]]
        _colors = np.asarray(_colors) / 255.0
        if min_lev is not None:
            idx = np.where(clevs >= min_lev)
            clevs = clevs[idx]
            _colors = _colors[idx, ]
        cmap, norm = mpl.colors.from_levels_and_colors(clevs,
                                                       _colors,
                                                       extend=extend)
        return {'clevs': clevs, 'cmap': cmap, 'norm': norm}

    elif name == 'ecmf_accumulated_rainfall':
        if clevs is None:
            clevs = [0.5, 10, 30, 50, 70, 100, 130, 160]
        clevs = np.asarray(clevs)
        _colors = np.array([
            '#a7aaaa', '#5cc8d7', '#3076bc', '#6aaa43', '#f5832a', '#ee2f2d',
            '#8350a0', '#231f20'
        ])
        if min_lev is not None:
            idx = np.where(clevs >= min_lev)
            clevs = clevs[idx]
            _colors = _colors[idx]
        cmap, norm = mpl.colors.from_levels_and_colors(clevs,
                                                       _colors,
                                                       extend=extend)
        return {'clevs': clevs, 'cmap': cmap, 'norm': norm}

    elif name == 'probability_forecast':
        if clevs is None:
            clevs = [1, 5, 10, 20, 30, 40, 50, 60, 70, 80, 90, 95, 100]
        clevs = np.asarray(clevs)
        cmap = cm.guide_cmaps(44)
        cmap = cm.truncate_colormap(cmap, maxval=0.95)
        norm = mpl.colors.BoundaryNorm(clevs, cmap.N, extend=extend)
        return {'clevs': clevs, 'cmap': cmap, 'norm': norm}

    elif name == 'ndfd_t_summer':
        if clevs is None:
            clevs = np.arange(0, 35, 2)
        clevs = np.asarray(clevs)
        cmap = cm.ndfd_cmaps('T_summer')
        norm = mpl.colors.BoundaryNorm(clevs, cmap.N, extend=extend)
        return {'clevs': clevs, 'cmap': cmap, 'norm': norm}

    elif name == '2m_temperature':
        if clevs is None:
            clevs = [
                -45, -30, -20, -10, -5, 0, 0, 5, 5, 10, 20, 20, 30, 30, 40, 45
            ]
        clevs = np.asarray(clevs)
        r = np.asarray([
            61, 250, 9, 94, 46, 6, 254, 32, 11, 0, 173, 254, 255, 255, 90, 253
        ])
        g = np.asarray([
            2, 0, 0, 157, 94, 249, 254, 178, 244, 97, 255, 254, 140, 99, 3, 253
        ])
        b = np.asarray([
            57, 252, 121, 248, 127, 251, 254, 170, 11, 3, 47, 0, 0, 61, 3, 253
        ])
        _colors = np.stack((r, g, b), axis=-1)
        _colors = np.asarray(_colors) / 255.0
        if min_lev is not None:
            idx = np.where(clevs >= min_lev)
            clevs = clevs[idx]
            _colors = _colors[idx, ]
        cmap, norm = mpl.colors.from_levels_and_colors(clevs,
                                                       _colors,
                                                       extend=extend)
        return {'clevs': clevs, 'cmap': cmap, 'norm': norm}

    else:
        raise ValueError('{} is not supported.'.format(name))
示例#4
0
def draw_theta_on_pv(ax,
                     lon,
                     lat,
                     theta,
                     mslp=None,
                     gh500=None,
                     map_extent=(73, 136, 18, 54),
                     theta_clev=np.arange(300, 400, 4),
                     alpha=0,
                     mslp_clev=np.arange(960, 1060, 4),
                     gh500_clev=np.arange(480, 600, 2),
                     cax=None,
                     left_title="850hPa wind",
                     right_title=None,
                     add_china=True,
                     coastline_color='black'):
    """
    Draw potential temperature on pv surface.

    :param ax: matplotlib axes.
    :param lon: longitude coordinates.
    :param lat: latitude coordinates.
    :param theta: potential temperature.
    :param mslp: mean sea level pressure.
    :param gh500: geopotential height 500hpa.
    :param map_extent: map extent.
    :param theta_clev: potential temperature.
    :param alpha: theta contour transparency.
    :param mslp_clev: mean sea level contour levels.
    :param gh500_clev: geopotential height 500 contour levels.
    :param cax: color bar axes.
    :param left_title: left title.
    :param right_title: right title.
    :param add_china: draw china province map or not.
    :param coastline_color: coast lines color.
    :return: potential temperature filled contour cf object.
    """

    # set data projection, should be longitude and latitude.
    datacrs = ccrs.PlateCarree()

    # clear figure
    ax.clear

    # set map extent
    ax.set_extent(map_extent)

    # add map boundary
    ax.coastlines('50m', edgecolor=coastline_color)
    if add_china:
        add_china_map_2cartopy(ax, name='province', edgecolor='darkcyan', lw=4)

    # draw potential temperature
    x, y = np.meshgrid(lon, lat)
    cmap = guide_cmaps("27")
    cf = ax.contourf(x,
                     y,
                     theta,
                     theta_clev,
                     cmap=cmap,
                     alpha=alpha,
                     antialiased=True,
                     transform=datacrs)
    if cax is not None:
        cb = plt.colorbar(cf,
                          cax=cax,
                          orientation='horizontal',
                          extendrect=True,
                          ticks=theta_clev)
        cb.set_label('Potential Temperature [K]', size='large', fontsize=16)
        cb.ax.tick_params(labelsize=16)

    # draw mean sea level pressure
    if mslp is not None:
        x, y = np.meshgrid(mslp[0], mslp[1])
        cs1 = ax.contour(x,
                         y,
                         mslp[2],
                         mslp_clev,
                         colors='k',
                         linewidth=1.0,
                         linestyles='solid',
                         transform=datacrs)
        plt.clabel(cs1,
                   fontsize=10,
                   inline=1,
                   inline_spacing=10,
                   fmt='%i',
                   rightside_up=True,
                   use_clabeltext=True)

    # draw 500hPa geopotential height
    if gh500 is not None:
        x, y = np.meshgrid(gh500[0], gh500[1])
        cs2 = ax.contour(x,
                         y,
                         gh500[2],
                         gh500_clev,
                         colors='w',
                         linewidth=1.0,
                         linestyles='dashed',
                         transform=datacrs)
        plt.clabel(cs2,
                   fontsize=10,
                   inline=1,
                   inline_spacing=10,
                   fmt='%i',
                   rightside_up=True,
                   use_clabeltext=True)

    # add grid lines
    gl = ax.gridlines(crs=ccrs.PlateCarree(),
                      draw_labels=True,
                      linewidth=2,
                      color='gray',
                      alpha=0.5,
                      linestyle='--')
    gl.xformatter = LONGITUDE_FORMATTER
    gl.yformatter = LATITUDE_FORMATTER
    gl.xlabels_top = False
    gl.ylabels_right = False
    gl.xlabel_style = {'size': 16}
    gl.ylabel_style = {'size': 16}

    # add title
    ax.set_title(left_title, loc='left', fontsize=18)
    if right_title is not None:
        ax.set_title(right_title, loc='right', fontsize=18)

    # return plot
    return cf
示例#5
0
def draw_wind850(ax,
                 lon,
                 lat,
                 u,
                 v,
                 mslp=None,
                 gh500=None,
                 thetae850=None,
                 map_extent=(73, 136, 18, 54),
                 wspeed_clev=np.arange(4, 40, 4),
                 mslp_clev=np.arange(960, 1060, 4),
                 wind_cmap=None,
                 gh500_clev=np.arange(480, 600, 2),
                 thetae850_clev=np.arange(280, 360, 4),
                 draw_barbs=True,
                 left_title="850hPa wind",
                 right_title=None,
                 add_china=True,
                 coastline_color='black',
                 title_font=None,
                 cax=None,
                 cb_title='850hPa wind speed (m/s)',
                 cb_font=None):
    """
    Draw 850hPa wind field.

    :param ax: matplotlib axes.
    :param lon: longitude coordinates.
    :param lat: latitude coordinates.
    :param u: u wind.
    :param v: v wind.
    :param mslp: mean sea level pressure, [lon, lat, mslp_data]
    :param gh500: 500hPa geopotential height, [lon, lat, gh500_data]
    :param thetae850: 850hPa equivalent potential temperature,
                      [lon, lat, thetae850_data]
    :param map_extent: map extent
    :param wspeed_clev: wind speed filled contour levels.
    :param mslp_clev: mean sea level contour levels.
    :param wind_cmap: wind filled contour color map.
    :param gh500_clev: geopotential height 500 contour levels.
    :param thetae850_clev: 850hPa theta contour levels.
    :param draw_barbs: flag for drawing wind barbs.
    :param cax: color bar axes, if None, no color bar will be draw.
    :param left_title: left title.
    :param right_title: right title.
    :param add_china: draw china province boundary or not.
    :param coastline_color: coast line color.
    :param title_font: title font properties, like:
                       title_font = mpl.font_manager.FontProperties(
                           fname='C:/Windows/Fonts/SIMYOU.TTF')
    :param cb_title: color bar title
    :param cb_font: color bar title font properties
    :return: wind filled contour cf and barbs bb object.

    """

    # set data projection, should be longitude and latitude.
    datacrs = ccrs.PlateCarree()

    # clear figure
    ax.clear

    # set map extent
    ax.set_extent(map_extent)

    # add map boundary
    ax.coastlines('50m', edgecolor=coastline_color)
    if add_china:
        add_china_map_2cartopy(ax, name='province', edgecolor='darkcyan')

    # draw 850hPa wind speed
    x, y = np.meshgrid(lon, lat)
    if wind_cmap is None:
        wind_cmap = guide_cmaps("2")
    cf = ax.contourf(x,
                     y,
                     np.sqrt(u * u + v * v),
                     wspeed_clev,
                     cmap=wind_cmap,
                     transform=datacrs)
    if cax is not None:
        cb = plt.colorbar(cf,
                          cax=cax,
                          orientation='horizontal',
                          extendrect=True,
                          ticks=wspeed_clev)
        cb.set_label(cb_title,
                     size='large',
                     fontsize=16,
                     fontproperties=cb_font)
        cb.ax.tick_params(labelsize=16)

    # draw wind barbs
    if draw_barbs:
        bb = ax.barbs(x,
                      y,
                      u,
                      v,
                      length=7,
                      regrid_shape=15,
                      transform=datacrs,
                      sizes=dict(emptybarb=0.05))

    # draw mean sea level pressure
    if mslp is not None:
        x, y = np.meshgrid(mslp[0], mslp[1])
        cs1 = ax.contour(x,
                         y,
                         mslp[2],
                         mslp_clev,
                         colors='k',
                         linewidth=1.0,
                         linestyles='solid',
                         transform=datacrs)
        plt.clabel(cs1,
                   fontsize=10,
                   inline=1,
                   inline_spacing=10,
                   fmt='%i',
                   rightside_up=True,
                   use_clabeltext=True)

    # draw 500hPa geopotential height
    if gh500 is not None:
        x, y = np.meshgrid(gh500[0], gh500[1])
        cs2 = ax.contour(x,
                         y,
                         gh500[2],
                         gh500_clev,
                         colors='w',
                         linewidth=1.0,
                         linestyles='dashed',
                         transform=datacrs)
        plt.clabel(cs2,
                   fontsize=10,
                   inline=1,
                   inline_spacing=10,
                   fmt='%i',
                   rightside_up=True,
                   use_clabeltext=True)

    # draw 850hPa equivalent potential temperature
    if thetae850 is not None:
        x, y = np.meshgrid(thetae850[0], thetae850[1])
        cmap = plt.get_cmap("hsv")
        cs3 = ax.contour(x,
                         y,
                         thetae850[2],
                         thetae850_clev,
                         cmap=cmap,
                         linewidth=0.8,
                         linestyles='solid',
                         transform=datacrs)
        plt.clabel(cs3,
                   fontsize=10,
                   inline=1,
                   inline_spacing=10,
                   fmt='%i',
                   rightside_up=True,
                   use_clabeltext=True)

    # add grid lines
    gl = ax.gridlines(crs=ccrs.PlateCarree(),
                      draw_labels=True,
                      linewidth=2,
                      color='gray',
                      alpha=0.5,
                      linestyle='--')
    gl.xformatter = LONGITUDE_FORMATTER
    gl.yformatter = LATITUDE_FORMATTER
    gl.xlabels_top = False
    gl.ylabels_right = False
    gl.xlabel_style = {'size': 16}
    gl.ylabel_style = {'size': 16}

    # add title
    ax.set_title(left_title,
                 loc='left',
                 fontsize=18,
                 fontproperties=title_font)
    if right_title is not None:
        ax.set_title(right_title,
                     loc='right',
                     fontsize=18,
                     fontproperties=title_font)

    # return plot
    if draw_barbs:
        return cf, bb
    else:
        return cf
示例#6
0
def draw_gh500_uv850_mslp(ax,
                          gh500=None,
                          uv850=None,
                          mslp=None,
                          map_extent=(50, 150, 0, 65),
                          add_china=True,
                          regrid_shape=20):
    """
    Draw 500-hPa geopotential height contours, 850-hPa wind barbs
    and mean sea level pressure filled contours.

    :param ax: `matplotlib.axes.Axes`, the `Axes` instance used for plotting.
    :param gh500: 500-hPa gh, dictionary:
                  necessary, {'lon': 1D array, 'lat': 1D array,
                              'data': 2D array}
                  optional, {'clevs': 1D array}
    :param uv850: 850-hPa u-component and v-component wind, dictionary:
                  necessary, {'lon': 1D array, 'lat': 1D array,
                              'udata': 2D array, 'vdata': 2D array}
    :param mslp: MSLP, dictionary:
                 necessary, {'lon': 1D array, 'lat': 1D array,
                             'data': 2D array}
                 optional, {'clevs': 1D array}
    :param map_extent: [lonmin, lonmax, latmin, latmax],
                       longitude and latitude range.
    :param add_china: add china map or not.
    :param regrid_shape: control the wind barbs density.
    :return: plots dictionary.

    :Examples:
    See dk_tool_weather_map.synoptic.gh500_uv850_mslp
    """

    # set data projection
    datacrs = ccrs.PlateCarree()

    # plot map background
    ax.set_extent(map_extent, crs=datacrs)
    ax.add_feature(cfeature.LAND, facecolor='0.6')
    ax.coastlines('50m', edgecolor='black', linewidth=0.75, zorder=100)
    if add_china:
        add_china_map_2cartopy(ax,
                               name='province',
                               edgecolor='darkcyan',
                               lw=1,
                               zorder=100)

    # define return plots
    plots = {}

    # draw mean sea level pressure
    if mslp is not None:
        x, y = np.meshgrid(mslp['lon'], mslp['lat'])
        clevs = mslp.get('clevs')
        if clevs is None:
            clevs = np.arange(960, 1065, 5)
        cmap = guide_cmaps(26)
        plots['mslp'] = ax.contourf(x,
                                    y,
                                    np.squeeze(mslp['data']),
                                    clevs,
                                    cmap=cmap,
                                    alpha=0.8,
                                    zorder=10,
                                    transform=datacrs)

    # draw 850-hPa wind bards
    if uv850 is not None:
        x, y = np.meshgrid(uv850['lon'], uv850['lat'])
        u = np.squeeze(uv850['udata']) * 2.5
        v = np.squeeze(uv850['vdata']) * 2.5
        plots['uv850'] = ax.barbs(x,
                                  y,
                                  u,
                                  v,
                                  length=6,
                                  regrid_shape=regrid_shape,
                                  transform=datacrs,
                                  fill_empty=False,
                                  sizes=dict(emptybarb=0.05),
                                  zorder=20)

    # draw 500-hPa geopotential height
    if gh500 is not None:
        x, y = np.meshgrid(gh500['lon'], gh500['lat'])
        clevs = gh500.get('clevs')
        if clevs is None:
            clevs = np.append(np.arange(480, 584, 8), np.arange(580, 604, 4))
        plots['gh500'] = ax.contour(x,
                                    y,
                                    np.squeeze(gh500['data']),
                                    clevs,
                                    colors='purple',
                                    linewidths=2,
                                    transform=datacrs,
                                    zorder=30)
        plt.clabel(plots['gh500'], inline=1, fontsize=16, fmt='%.0f')

    # grid lines
    gl = ax.gridlines(crs=datacrs,
                      linewidth=2,
                      color='gray',
                      alpha=0.5,
                      linestyle='--')
    gl.xlocator = mpl.ticker.FixedLocator(np.arange(0, 360, 15))
    gl.ylocator = mpl.ticker.FixedLocator(np.arange(-90, 90, 15))

    # return plots
    return plots
示例#7
0
def draw_uv850(ax,
               uv850=None,
               gh850=None,
               map_extent=(73, 136, 18, 54),
               add_china=True,
               regrid_shape=15):
    """
    Draw 850-hPa wind field.

    :param ax: `matplotlib.axes.Axes`, the `Axes` instance used for plotting.
    :param uv850: 850-hPa u-component and v-component wind, dictionary:
                  necessary, {'lon': 1D array, 'lat': 1D array,
                              'udata': 2D array, 'vdata': 2D array}
                  optional, {'clevs': 1D array speed contour levels}
    :param gh850: optional, {'clevs': 1D array}
    :param map_extent: [lonmin, lonmax, latmin, latmax],
                       longitude and latitude range.
    :param add_china: add china map or not.
    :param regrid_shape: control the wind barbs density.
    :return: plots dictionary.
    """

    # set data projection
    datacrs = ccrs.PlateCarree()

    # plot map background
    ax.set_extent(map_extent, crs=datacrs)
    ax.add_feature(cfeature.LAND, facecolor='0.6')
    ax.coastlines('50m', edgecolor='black', linewidth=0.75, zorder=100)
    if add_china:
        add_china_map_2cartopy(ax,
                               name='province',
                               edgecolor='darkcyan',
                               lw=1,
                               zorder=100)

    # define return plots
    plots = {}

    # draw 850hPa wind speed and barbs
    if uv850 is not None:
        x, y = np.meshgrid(uv850['lon'], uv850['lat'])
        u = np.squeeze(uv850['udata'])
        v = np.squeeze(uv850['vdata'])
        clevs = uv850.get('clevs')
        if clevs is None:
            clevs = np.arange(4, 40, 4)
        cmaps = guide_cmaps("2")
        plots['uv850_cf'] = ax.contourf(x,
                                        y,
                                        np.sqrt(u * u + v * v),
                                        clevs,
                                        cmap=cmaps,
                                        transform=datacrs)
        plots['uv850_bb'] = ax.barbs(x,
                                     y,
                                     u * 2.5,
                                     v * 2.5,
                                     length=7,
                                     regrid_shape=regrid_shape,
                                     transform=datacrs,
                                     sizes=dict(emptybarb=0.05))

    # draw 850hPa geopotential height
    if gh850 is not None:
        x, y = np.meshgrid(gh850['lon'], gh850['lat'])
        clevs = gh850.get('clevs')
        if clevs is None:
            clevs = np.arange(80, 180, 4)
        plots['gh850'] = ax.contour(x,
                                    y,
                                    np.squeeze(gh850['data']),
                                    clevs,
                                    colors='purple',
                                    linewidths=2,
                                    transform=datacrs,
                                    zorder=30)
        plt.clabel(plots['gh850'], inline=1, fontsize=16, fmt='%.0f')

    # add grid lines
    gl = ax.gridlines(crs=ccrs.PlateCarree(),
                      draw_labels=True,
                      linewidth=2,
                      color='gray',
                      alpha=0.5,
                      linestyle='--')
    gl.xformatter = LONGITUDE_FORMATTER
    gl.yformatter = LATITUDE_FORMATTER
    gl.xlabels_top = False
    gl.ylabels_right = False
    gl.xlabel_style = {'size': 16}
    gl.ylabel_style = {'size': 16}

    # return
    return plots