def main(): p = ArgumentParser(description="calls IGRF from Python, and plots " "the modeled geomagnetic field") p.add_argument("date", help="date of sim", nargs="?", default=datetime.date.today()) p.add_argument("--isv", help="0: main field. 1: secular variation", type=int, default=0) p.add_argument("--itype", help="1: geodetic. 2: geocentric", type=int, default=1) p.add_argument( "-a", "--altkm", help="(km) above sea level if itype=1," " (km) from center of Earth if itype=2", type=float, nargs="+", default=0, ) p.add_argument("-c", "--latlon", help="geodetic latitude, longitude (deg)", type=float, nargs=2) P = p.parse_args() # do world-wide grid if no user input if not P.altkm or not P.latlon: glat, glon = igrf12.latlonworldgrid() elif P.altkm and P.latlon: glat, glon = P.latlon else: raise ValueError("please input all 3 of lat,lon,alt or none of them") mag12: xarray.Dataset = igrf12.gridigrf12(P.date, glat, glon, P.altkm, P.isv, P.itype) # mag11 = igrf12.testigrf11(p.date,glat,glon,p.altkm, p.isv, p.itype) if glat.ndim == 2: plt.plotigrf(mag12, "12") # plt.plotdiff1112(mag12,mag11) else: print(mag12) show()
def main(): p = ArgumentParser(description='calls IGRF from Python, and plots ' 'the modeled geomagnetic field') p.add_argument('date', help='date of sim', nargs='?', default=datetime.date.today()) p.add_argument('--isv', help='0: main field. 1: secular variation', type=int, default=0) p.add_argument('--itype', help='1: geodetic. 2: geocentric', type=int, default=1) p.add_argument('-a', '--altkm', help='(km) above sea level if itype=1,' ' (km) from center of Earth if itype=2', type=float, nargs='+', default=0) p.add_argument('-c', '--latlon', help='geodetic latitude, longitude (deg)', type=float, nargs=2) P = p.parse_args() # do world-wide grid if no user input if not P.altkm or not P.latlon: glat, glon = igrf12.latlonworldgrid() elif P.altkm and P.latlon: glat, glon = P.latlon else: raise ValueError('please input all 3 of lat,lon,alt or none of them') mag12: xarray.Dataset = igrf12.gridigrf12(P.date, glat, glon, P.altkm, P.isv, P.itype) # mag11 = igrf12.testigrf11(p.date,glat,glon,p.altkm, p.isv, p.itype) if glat.ndim == 2: plt.plotigrf(mag12, '12') # plt.plotdiff1112(mag12,mag11) else: print(mag12) show()
def plotCartoMap(latlim=None, lonlim=None, parallels=None, meridians=None, pole_center_lon=0, figsize=(12, 8), terrain=False, ax=False, projection='stereo', title='', resolution='110m', states=True, grid_linewidth=0.5, grid_color='black', grid_linestyle='--', background_color=None, border_color='k', figure=False, nightshade=False, ns_dt=None, ns_alpha=0.1, apex=False, igrf=False, date=None, mlat_levels=None, mlon_levels=None, alt_km=0.0, mlon_colors='blue', mlat_colors='red', mgrid_width=1, mgrid_labels=True, mgrid_fontsize=12, mlon_cs='mlon', incl_levels=None, decl_levels=None, igrf_param='incl', mlon_labels=True, mlat_labels=True, mgrid_style='--', label_colors='k', decl_colors='k', incl_colors='k'): if lonlim is None: if projection in ['southpole', 'northpole']: lonlim = [-180, 180] else: lonlim = [-40, 40] if latlim is None: if projection is'southpole': latlim = [-90, 0] elif projection is 'northpole': latlim = [90, 0] else: latlim = [0, 75] STATES = cfeature.NaturalEarthFeature( category='cultural', name='admin_1_states_provinces_lines', scale='50m', facecolor='none') if not ax: if figsize is None: fig = plt.figure() else: fig = plt.figure(figsize=figsize) if projection == 'stereo': ax = plt.axes(projection=ccrs.Stereographic(central_longitude=(sum(lonlim) / 2))) elif projection == 'merc': ax = plt.axes(projection=ccrs.Mercator()) elif projection == 'plate': ax = plt.axes(projection=ccrs.PlateCarree(central_longitude=(sum(lonlim) / 2))) elif projection == 'lambert': ax = plt.axes(projection=ccrs.LambertConformal(central_longitude=(sum(lonlim) / 2), central_latitude=(sum(latlim) / 2))) elif projection == 'mollweide': ax = plt.axes(projection=ccrs.Mollweide(central_longitude=(sum(lonlim) / 2))) elif projection == 'northpole': ax = plt.axes(projection=ccrs.NorthPolarStereo()) ax.set_boundary(circle, transform=ax.transAxes) # polarLim(ax, projection) elif projection == 'southpole': ax = plt.axes(projection=ccrs.SouthPolarStereo()) ax.set_boundary(circle, transform=ax.transAxes) # polarLim(ax, projection) if background_color is not None: ax.background_patch.set_facecolor(background_color) ax.set_title(title) ax.coastlines(color=border_color, resolution=resolution) # 110m, 50m or 10m if states: ax.add_feature(STATES, edgecolor=border_color) ax.add_feature(cfeature.BORDERS, edgecolor=border_color) if terrain: ax.stock_img() if nightshade: assert ns_dt is not None assert ns_alpha is not None ax.add_feature(Nightshade(ns_dt, ns_alpha)) # Draw Parallels if projection == 'merc' or projection == 'plate': if isinstance(meridians, np.ndarray): meridians = list(meridians) if isinstance(parallels, np.ndarray): parallels = list(parallels) gl = ax.gridlines(crs=ccrs.PlateCarree(), color=grid_color, draw_labels=False, linestyle=grid_linestyle, linewidth=grid_linewidth) if meridians is None: gl.xlines = False else: if len(meridians) > 0: gl.xlocator = mticker.FixedLocator(meridians) gl.xlabels_bottom = True else: gl.ylines = False if parallels is None: gl.ylines = False else: if len(parallels) > 0: gl.ylocator = mticker.FixedLocator(parallels) # ax.yaxis.set_major_formatter(LONGITUDE_FORMATTER) gl.ylabels_left = True else: gl.ylines = False else: gl = ax.gridlines(crs=ccrs.PlateCarree(), color=grid_color, draw_labels=False, linestyle=grid_linestyle, linewidth=grid_linewidth) if meridians is None: gl.xlines = False else: # if isinstance(meridians, np.ndarray): # meridians = list(meridians) # ax.xaxis.set_major_formatter(LONGITUDE_FORMATTER) # ax.yaxis.set_major_formatter(LATITUDE_FORMATTER) # if isinstance(meridians, np.ndarray): # meridians = list(meridians) gl.xlocator = mticker.FixedLocator(meridians) # else: # gl.xlines = False if parallels is not None: if isinstance(parallels, np.ndarray): parallels = list(parallels) gl.ylocator = mticker.FixedLocator(parallels) else: gl.ylines = False # Geomagnetic coordinates @ Apex if apex: if date is None: date = datetime(2017, 12, 31, 0, 0, 0) assert isinstance(date, datetime) A = ap.Apex(date=date) # Define levels and ranges for conversion if mlon_cs == 'mlt': if mlon_levels is None: mlon_levels = np.array([]) mlon_range = np.arange(0, 24.1, 0.1) elif isinstance(mlon_levels, bool): if mlon_levels == False: mlon_levels = np.array([]) mlon_range = np.arange(0, 24.1, 0.1) else: mlon_range = np.arange(mlon_levels[0], mlon_levels[-1] + 0.1, 0.1) else: if mlon_levels is None: mlon_levels = np.array([]) mlon_range = np.arange(-180, 180, 0.5) elif isinstance(mlon_levels, bool): if mlon_levels == False: mlon_levels = np.array([]) mlon_range = np.arange(-180, 181, 0.1) else: mlon_range = np.arange(mlon_levels[0], mlon_levels[0] + 362, 0.1) if mlat_levels is None: mlat_levels = np.arange(-90, 90.1, 5) mlat_range = np.arange(mlat_levels[0], mlat_levels[-1] + 0.1, 0.1) # Do meridans for mlon in mlon_levels: MLON = mlon * np.ones(mlat_range.size) if mlon_cs == 'mlt': y, x = A.convert(mlat_range, MLON, 'mlt', 'geo', datetime=date) else: y, x = A.convert(mlat_range, MLON, 'apex', 'geo') # Plot meridian inmap = np.logical_and(x >= lonlim[0], x <= lonlim[1]) if np.sum(inmap) > 10: ax.plot(np.unwrap(x, 180), np.unwrap(y, 90), c=mlon_colors, lw=mgrid_width, linestyle=mgrid_style, transform=ccrs.PlateCarree()) # Labels if mlon_labels: ix = np.argmin(abs(y - np.mean(latlim))) mx = x[ix] - 1 if mlon >= 10 else x[ix] - 0.5 my = np.mean(latlim) if np.logical_and(mx >= lonlim[0], mx <= lonlim[1]): if mlon_cs == 'mlt' and mlon != 0: ax.text(mx, my, str(int(mlon)), color=label_colors, fontsize=14, backgroundcolor='white', transform=ccrs.PlateCarree()) elif mlon_cs != 'mlt' and mlon != 360: ax.text(mx, my, str(int(mlon)), color=label_colors, fontsize=14, backgroundcolor='white', transform=ccrs.PlateCarree()) # Do parallels for mlat in mlat_levels: MLAT = mlat * np.ones(mlon_range.size) if mlon_cs == 'mlt': gy, gx = A.convert(MLAT, mlon_range, 'mlt', 'geo', datetime=date) else: gy, gx = A.convert(MLAT, mlon_range, 'apex', 'geo', datetime=date) inmap = np.logical_and(gy >= latlim[0], gy <= latlim[1]) if np.sum(inmap) > 2: ax.plot(np.unwrap(gx, 180), np.unwrap(gy, 90), c=mlat_colors, lw=mgrid_width, linestyle=mgrid_style, transform=ccrs.PlateCarree()) # Labels if mlat_labels: ix = np.argmin(abs(gx - np.mean(lonlim))) mx = np.mean(lonlim) my = gy[ix] - 0.5 if np.logical_and(mx >= lonlim[0], mx <= lonlim[1]) and \ np.logical_and(my >= latlim[0], my <= latlim[1]): ax.text(mx, my, str(int(mlat)), color=label_colors, fontsize=14, backgroundcolor='white', transform=ccrs.PlateCarree()) if igrf: glon = np.arange(lonlim[0] - 40, lonlim[1] + 40.1, 0.5) glat = np.arange(-90, 90 + 0.1, 0.5) longrid, latgrid = np.meshgrid(glon, glat) mag = igrf12.gridigrf12(t=date, glat=latgrid, glon=longrid, alt_km=alt_km) if decl_levels is not None: z = mag.decl.values for declination in decl_levels: ax.contour(longrid, latgrid, z, levels=declination, colors=decl_colors, transform=ccrs.PlateCarree()) if incl_levels is not None: z = mag.incl.values for inclination in incl_levels: ax.contour(longrid, latgrid, z, levels=declination, colors=incl_colors, transform=ccrs.PlateCarree()) # Set Extent ax.set_extent([lonlim[0], lonlim[1], latlim[0], latlim[1]], crs=ccrs.PlateCarree()) if 'fig' in locals(): return fig, ax else: return ax
def plotCartoMap(latlim=[0, 75], lonlim=[-40, 40], parallels=None, meridians=None, pole_center_lon=0, figsize=(12, 8), terrain=False, ax=False, projection='stereo', title='', resolution='110m', lon0=None, lat0=None, states=True, grid_linewidth=0.5, grid_color='black', grid_linestyle='--', background_color=None, border_color='k', figure=False, nightshade=False, ns_alpha=0.1, apex=False, igrf=False, date=None, mlat_levels=None, mlon_levels=None, alt_km=0.0, mlon_colors='blue', mlat_colors='red', mgrid_width=1, mgrid_labels=True, mgrid_fontsize=12, mlon_cs='mlon', incl_levels=None, decl_levels=None, igrf_param='incl', mlon_labels=True, mlat_labels=True, mgrid_style='--', label_colors='k', apex_alt=0, decl_colors='k', incl_colors='k', terminator=False, terminator_altkm=350, polarization_terminator=False, pt_hemisphere='north', ter_color='red', ter_style='--', ter_width=2, midnight=False, midnight_colors='m', midnight_width=2, midnight_style='--'): if lonlim is None or lonlim == []: lonlim = [-180, 180] STATES = cfeature.NaturalEarthFeature( category='cultural', name='admin_1_states_provinces_lines', scale='50m', facecolor='none') if not ax: if figsize is None: fig = plt.figure() else: fig = plt.figure(figsize=figsize) if projection == 'stereo': ax = plt.axes(projection=ccrs.Stereographic( central_longitude=(sum(lonlim) / 2))) elif projection == 'merc': ax = plt.axes(projection=ccrs.Mercator()) elif projection == 'plate': ax = plt.axes(projection=ccrs.PlateCarree( central_longitude=(sum(lonlim) / 2))) elif projection == 'lambert': ax = plt.axes(projection=ccrs.LambertConformal( central_longitude=(sum(lonlim) / 2), central_latitude=(sum(latlim) / 2))) elif projection == 'mollweide': ax = plt.axes(projection=ccrs.Mollweide( central_longitude=(sum(lonlim) / 2))) elif projection == 'north': if lon0 is None: lon0 = 0 ax = plt.axes(projection=ccrs.NorthPolarStereo( central_longitude=lon0)) elif projection == 'south': if lon0 is None: lon0 = 0 ax = plt.axes(projection=ccrs.SouthPolarStereo( central_longitude=lon0)) elif projection == 'ortographic': if lon0 is None: lon0 = 0 if lat0 is None: lat0 = 0 ax = plt.axes(projection=ccrs.Orthographic(central_longitude=lon0, central_latitude=lat0)) else: print("Projection is invalid. Please enter the right one. \n \ 'stereo', 'merc', 'plate', 'lambret', mollweide', 'north, 'south', 'ortographic'" ) return 0 if background_color is not None: ax.background_patch.set_facecolor(background_color) ax.set_title(title) ax.coastlines(color=border_color, resolution=resolution) # 110m, 50m or 10m if states: ax.add_feature(STATES, edgecolor=border_color) ax.add_feature(cfeature.BORDERS, edgecolor=border_color) if terrain: ax.stock_img() if nightshade: assert date is not None assert ns_alpha is not None ax.add_feature(Nightshade(date, ns_alpha)) # Draw Parralels if projection == 'merc' or projection == 'plate': if isinstance(meridians, np.ndarray): meridians = list(meridians) if isinstance(parallels, np.ndarray): parallels = list(parallels) gl = ax.gridlines(crs=ccrs.PlateCarree(), color=grid_color, draw_labels=False, linestyle=grid_linestyle, linewidth=grid_linewidth) if meridians is None: gl.xlines = False else: if len(meridians) > 0: gl.xlocator = mticker.FixedLocator(meridians) gl.xlabels_bottom = True else: gl.ylines = False if parallels is None: gl.ylines = False else: if len(parallels) > 0: gl.ylocator = mticker.FixedLocator(parallels) gl.ylabels_left = True else: gl.ylines = False else: gl = ax.gridlines(crs=ccrs.PlateCarree(), color=grid_color, draw_labels=False, linestyle=grid_linestyle, linewidth=grid_linewidth) if meridians is None: gl.xlines = False else: gl.xlocator = mticker.FixedLocator(meridians) if parallels is not None: if isinstance(parallels, np.ndarray): parallels = list(parallels) gl.ylocator = mticker.FixedLocator(parallels) else: gl.ylines = False # Geomagnetic coordinates @ Apex if apex: if date is None: date = datetime(2017, 12, 31, 0, 0, 0) assert isinstance(date, datetime) A = ap.Apex(date=date) # Define levels and ranges for conversion if mlon_cs == 'mlt': if mlon_levels is None: mlon_levels = np.array([]) mlon_range = np.arange(0, 24.01, 0.01) elif isinstance(mlon_levels, bool): if mlon_levels == False: mlon_levels = np.array([]) mlon_range = np.arange(0, 24.01, 0.01) else: mlon_range = np.arange(mlon_levels[0], mlon_levels[-1] + 0.1, 0.01) else: if mlon_levels is None: mlon_levels = np.array([]) mlon_range = np.arange(-180, 180, 0.5) elif isinstance(mlon_levels, bool): if mlon_levels == False: mlon_levels = np.array([]) mlon_range = np.arange(-180, 181, 0.1) else: mlon_range = np.arange(mlon_levels[0], mlon_levels[0] + 362, 0.1) if mlat_levels is None: mlat_levels = np.arange(-90, 90.1, 1) mlat_range = np.arange(mlat_levels[0], mlat_levels[-1] + 0.1, 0.1) # Do meridans for mlon in mlon_levels: MLON = mlon * np.ones(mlat_range.size) if mlon_cs == 'mlt': y, x = A.convert(mlat_range, MLON, 'mlt', 'geo', datetime=date, height=apex_alt) else: y, x = A.convert(mlat_range, MLON, 'apex', 'geo', height=apex_alt) mlat_mask_extent = (y >= latlim[0] + 0.2) & (y <= latlim[1] - 0.2) # Plot meridian inmap = np.logical_and(x >= lonlim[0], x <= lonlim[1]) if np.sum(inmap) > 10: ax.plot(np.unwrap(x[mlat_mask_extent], 180), np.unwrap(y[mlat_mask_extent], 90), c=mlon_colors, lw=mgrid_width, linestyle=mgrid_style, zorder=90, transform=ccrs.PlateCarree()) # Labels if mlon_labels: ix = abs(y - np.mean(latlim)).argmin() mx = x[ix] - 1 if mlon >= 10 else x[ix] - 0.5 my = np.mean(latlim) if np.logical_and(mx >= lonlim[0], mx <= lonlim[1]): if mlon_cs == 'mlt' and mlon != 0: ax.text(mx, my, str(int(mlon)), color=label_colors, fontsize=14, backgroundcolor='white', transform=ccrs.PlateCarree()) elif mlon_cs != 'mlt' and mlon != 360: ax.text(mx, my, str(int(mlon)), color=label_colors, fontsize=14, backgroundcolor='white', transform=ccrs.PlateCarree()) # Do parallels for mlat in mlat_levels: MLAT = mlat * np.ones(mlon_range.size) if mlon_cs == 'mlt': gy, gx = A.convert(MLAT, mlon_range, 'mlt', 'geo', datetime=date, height=apex_alt) else: gy, gx = A.convert(MLAT, mlon_range, 'apex', 'geo', datetime=date, height=apex_alt) inmap = np.logical_and(gy >= latlim[0], gy <= latlim[1]) if np.sum(inmap) > 20: ax.plot(np.unwrap(gx, 180), np.unwrap(gy, 90), c=mlat_colors, lw=mgrid_width, linestyle=mgrid_style, zorder=90, transform=ccrs.PlateCarree()) # Labels if mlat_labels: ix = abs(gx - np.mean(lonlim)).argmin() mx = np.mean(lonlim) my = gy[ix] - 0.5 if np.logical_and(mx >= lonlim[0], mx <= lonlim[1]) and \ np.logical_and(my >= latlim[0], my <= latlim[1]): ax.text(mx, my, str(int(mlat)), color=label_colors, fontsize=14, backgroundcolor='white', transform=ccrs.PlateCarree()) if igrf: glon = np.arange(lonlim[0] - 40, lonlim[1] + 40.1, 0.5) glat = np.arange(-90, 90 + 0.1, 0.5) longrid, latgrid = np.meshgrid(glon, glat) mag = igrf12.gridigrf12(t=date, glat=latgrid, glon=longrid, alt_km=alt_km) if decl_levels is not None: z = mag.decl.values for declination in decl_levels: ax.contour(longrid, latgrid, z, levels=declination, zorder=90, colors=decl_colors, transform=ccrs.PlateCarree()) if incl_levels is not None: z = mag.incl.values for inclination in incl_levels: ax.contour(longrid, latgrid, z, levels=declination, zorder=90, colors=incl_colors, transform=ccrs.PlateCarree()) # Terminators if terminator: assert date is not None if not isinstance(terminator_altkm, list): terminator_altkm = [terminator_altkm] for takm in terminator_altkm: try: glon_ter, glat_ter = ter.get_terminator(date, alt_km=takm) if glon_ter is not None and glat_ter is not None: if isinstance(glon_ter, list): for i in range(len(glon_ter)): ax.plot(np.unwrap(glon_ter[i], 180), np.unwrap(glat_ter[i], 90), c=ter_color, lw=ter_width, ls=ter_style, zorder=90, transform=ccrs.PlateCarree()) else: ax.plot(np.unwrap(glon_ter, 180), np.unwrap(glat_ter, 90), c=ter_color, lw=ter_width, ls=ter_style, zorder=90, transform=ccrs.PlateCarree()) except: pass if midnight: mlat_range = np.arange(-89.9, 90.1, 0.1) MLON = 0 * np.ones(mlat_range.size) if mlon_cs == 'mlt': y, x = A.convert(mlat_range, MLON, 'mlt', 'geo', datetime=date, height=apex_alt) else: y, x = A.convert(mlat_range, MLON, 'apex', 'geo', height=apex_alt) mlat_mask_extent = (y >= latlim[0] + 0.2) & (y <= latlim[1] - 0.2) # Plot meridian inmap = np.logical_and(x >= lonlim[0], x <= lonlim[1]) if np.sum(inmap) > 10: ax.plot(np.unwrap(x[mlat_mask_extent], 180), np.unwrap(y[mlat_mask_extent], 90), c=midnight_colors, lw=midnight_width, linestyle=midnight_style, zorder=90, transform=ccrs.PlateCarree()) # Set Extent if projection == 'north' or projection == 'south': import matplotlib.path as mpath ax.set_extent([-180, 181, latlim[0], latlim[1]], crs=ccrs.PlateCarree()) 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) ax.set_boundary(circle, transform=ax.transAxes) elif lonlim[0] != -180 and lonlim[1] != 180: ax.set_extent([lonlim[0], lonlim[1], latlim[0], latlim[1]], crs=ccrs.PlateCarree()) #ccrs.PlateCarree()) if 'fig' in locals(): return fig, ax else: return ax
fig = gm.plotCartoMap( projection='stereo', title='Magnetic declination angle. Ground (solid), 150 km (dashed)', latlim=latlim, lonlim=lonlim, parallels=[20, 40, 60, 80, 90], meridians=[-220, -180, -160, -140, -120, -100, -80, -60, -40, 0], grid_linewidth=1, figure=True, states=False) glon = np.arange(0, 360, 1) glat = np.arange(-90, 90.1, 1) longrid, latgrid = np.meshgrid(glon, glat) mag0 = igrf12.gridigrf12(t=date, glat=latgrid, glon=longrid, alt_km=0.0) mag150 = igrf12.gridigrf12(t=date, glat=latgrid, glon=longrid, alt_km=150.0) # Declination #ai = plt.contour(longrid, latgrid, mag0.decl.values, levels=np.arange(-30,30.1,1), # cmap='bwr', transform=ccrs.PlateCarree()) #ai = plt.contour(longrid, latgrid, mag150.decl.values, levels=np.arange(-30,30.1,1), # cmap='bwr', transform=ccrs.PlateCarree(), linestyles='dashed') #plt.contour(longrid, latgrid, mag150.decl.values, levels=np.arange(0,1,1), # colors='green', transform=ccrs.PlateCarree(), linestyles='solid') #ai.clabel(inline=True, fmt = '%d', fontsize=12, colors='b') #Inclination ai = plt.contour(longrid, latgrid, mag0.incl.values,