Exemplo n.º 1
0
def global_predstorm_noaa(world_image):



 fig = plt.figure(1,figsize=[15, 10]) 
 fig.set_facecolor('black') 

 #axis PREDSTORM + OVATION
 ax1 = plt.subplot(1, 2, 1, projection=ccrs.Orthographic(global_plot_longitude, global_plot_latitude))
 #axis NOAA 
 ax2 = plt.subplot(1, 2, 2, projection=ccrs.Orthographic(global_plot_longitude, global_plot_latitude))
 #load NOAA nowcast
 noaa_img, dt = oup.aurora_now()


 for ax in [ax1,ax2]:

     ax.gridlines(linestyle='--',alpha=0.5,color='white')
     #ax.coastlines(alpha=0.5,zorder=3)
     #ax.add_feature(land_50m, color='darkgreen') 

     #ax.add_feature(land_50m, color='darkslategrey')
     #ax.add_feature(carfeat.LAND,color='darkslategrey')
     #ax.add_feature(carfeat.LAKES,color='navy')#,zorder=2,alpha=1)
     #ax.add_feature(carfeat.OCEAN)#,zorder=2,alpha=1)
     #ax.add_feature(ocean_50m,linewidth=0.5, color='navy')

     #ax.add_feature(carfeat.BORDERS, alpha=0.5)#,zorder=2,alpha=0.5)
     #ax.add_feature(carfeat.COASTLINE)#,zorder=2,alpha=0.5)
     #ax.add_feature(carfeat.RIVERS)#,zorder=2,alpha=0.8)
     #ax.add_feature(provinces_50m,alpha=0.5)#,zorder=2,alpha=0.8)
     ax.stock_img()#alpha=0.2)
    
     #ax.add_wmts(nightmap, layer)
  
     #for testing with black background
     #ax.background_patch.set_facecolor('k')    
     if ax==ax1: 
        ax.imshow(world_image, vmin=0, vmax=100, transform=crs, extent=mapextent, origin='lower', zorder=3, alpha=0.9, cmap=oup.aurora_cmap())
        ax.add_feature(Nightshade(t0))

     if ax==ax2: 
        ax.imshow(noaa_img, vmin=0, vmax=100, transform=crs, extent=mapextent, origin='lower', zorder=3, alpha=0.9, cmap=oup.aurora_cmap())
        ax.add_feature(Nightshade(dt))

   
    
 fig.text(0.01,0.92,'PREDSTORM aurora forecast   '+t0.strftime('%Y-%m-%d %H:%M UT' )+ '                                                            NOAA forecast  '+dt.strftime('%Y-%m-%d %H:%M UT' ), color='white',fontsize=15)
 fig.text(0.99,0.02,'C. Möstl / IWF-helio, Austria', color='white',fontsize=8,ha='right')
 plt.tight_layout()  
 plot_Nhemi_comparison_filename='test/predstorm_aurora_real_Nhemi_'+t0.strftime("%Y_%m_%d_%H%M")  +'.jpg'
 fig.savefig(plot_Nhemi_comparison_filename,dpi=120,facecolor=fig.get_facecolor())
 #plt.show()
 print('Saved image:  ',plot_Nhemi_comparison_filename)
Exemplo n.º 2
0
    def __init__(self, metric_name, date, decorations=True):
        self.metric_name = metric_name
        self.date = date
        self.decorations = decorations
        self.plotalpha = 0.35

        self.fig = plt.figure(figsize=(16,24))
        self.ax = plt.axes(
            projection=ccrs.PlateCarree(),
            frame_on=self.decorations,
        )
        self.ax.set_global()

        if self.decorations:
            self.ax.grid(linewidth=.5, color='black', alpha=0.25, linestyle='--')
            self.ax.set_xticks([-180, -160, -140, -120,-100, -80, -60,-40,-20, 0, 20, 40, 60,80,100, 120,140, 160,180], crs=ccrs.PlateCarree())
            self.ax.set_yticks([-80, -60,-40,-20, 0, 20, 40, 60,80], crs=ccrs.PlateCarree())
        else:
            self.ax.axis(False)
            self.ax.outline_patch.set_visible(False)
            self.ax.background_patch.set_visible(False)
            self.ax.set_xmargin(0)
            self.ax.set_ymargin(0)

        self.ax.add_feature(cartopy.feature.NaturalEarthFeature('physical', 'land', '110m',
            edgecolor='face',
            facecolor=np.array((0xdd,0xdd,0xcc))/256.,
            zorder=-1
            )
        )

        self.ax.add_feature(Nightshade(self.date, alpha=0.08))
Exemplo n.º 3
0
def test_nightshade_floating_point():
    # Smoke test for clipping nightshade floating point values
    date = datetime(1999, 12, 31, 12)

    # This can cause an error with floating point precision if it is
    # set to exactly -6 and arccos input is not clipped to [-1, 1]
    Nightshade(date, refraction=-6.0, color='none')
Exemplo n.º 4
0
def test_nightshade_image():
    # Test the actual creation of the image
    ax = plt.axes(projection=ccrs.PlateCarree())
    ax.coastlines()
    dt = datetime(2018, 11, 10, 0, 0)
    ax.set_global()
    ax.add_feature(Nightshade(dt, alpha=0.75))
Exemplo n.º 5
0
 def add_dn_terminator(self, **kwargs):
     """ Adding day night terminator """
     from cartopy.feature.nightshade import Nightshade
     if self.plot_date:
         ns_feature = Nightshade(self.plot_date, alpha=0.2)
         super().add_feature(feature, **kwargs)
     return
Exemplo n.º 6
0
    def _plot_orthographic_projection(latitude_sat, longitude_sat,
                                      lat_footprint, lon_footprint, epoch):
        """This method plots the satellite track and footprint in the Orthographic projection.

        INPUT:
        ------
        latitude_sat    =   vector of latitudes of the satellite. It must be of the same size of longitude_sat. [deg]
        longitude_sat   =   vector of longitudes of the satellite. It must be of the same size of latitude_sat. [deg]
        lat_footprint   =   vector of latitudes of the boundary of the satellite footprint. [deg]
                            It must be of the same size of lon_footprint.
        lon_footprint   =   vector of longitudes of the boundary of the satellite footprint.  [deg]
                            It must be of the same size of lat_footprint.
        epoch           =   epoch to display the nightshade on the map. It must be of type datetime.
        """
        plt.figure()
        ax = plt.axes(
            projection=ccrs.Orthographic(longitude_sat[0], latitude_sat[0]))
        points = ccrs.Orthographic(longitude_sat[0],
                                   latitude_sat[0]).transform_points(
                                       ccrs.Geodetic(), longitude_sat,
                                       latitude_sat)
        footprint_points = ccrs.Orthographic(longitude_sat[0],
                                             latitude_sat[0]).transform_points(
                                                 ccrs.Geodetic(),
                                                 lon_footprint, lat_footprint)
        ax.gridlines()
        ax.coastlines()
        ax.set_global()
        ax.add_feature(Nightshade(epoch, alpha=0.4))
        ax.plot(points[:, 0], points[:, 1], linewidth=2)
        ax.plot(footprint_points[:, 0], footprint_points[:, 1], linewidth=2)
        ax.plot(points[0, 0], points[0, 1], 'h', color='#1e1596', markersize=8)
Exemplo n.º 7
0
def plot_clear(dtime, show=True):
    """
    Plot an orthographic projection of clear area.

    - dtime = datetime instance
    - show = boolean: whether or not to display a plot

    Either shows a plot and returns nothing, or returns the axis on which
    the clear area is plotted, depending on the value of "show".
    """
    print('plotting clear area')

    # general earth setup
    ax = plt.axes(projection=constants.ortho)
    ax.add_feature(cartopy.feature.OCEAN, zorder=0)
    ax.add_feature(cartopy.feature.LAND, zorder=0, edgecolor='black')
    ax.add_feature(cartopy.feature.BORDERS, zorder=0, edgecolor='black')
    ax.add_feature(Nightshade(dtime, alpha=0.2))

    # add clear polys
    clear_polys, _ = earth_data.get_clear(dtime)
    print("adding", len(clear_polys), "clear polygons to plot")
    ax.add_geometries(clear_polys, crs=constants.lonlat, facecolor='g')

    # show the plot if desired
    if show:
        plt.show()
    else:
        # return the axis so we can plot more things overtop if we want
        return ax
Exemplo n.º 8
0
def main():
    fig = plt.figure(figsize=[10, 5])

    # We choose to plot in an Orthographic projection as it looks natural
    # and the distortion is relatively small around the poles where
    # the aurora is most likely.

    # ax1 for Northern Hemisphere
    ax1 = fig.add_subplot(1, 2, 1, projection=ccrs.Orthographic(0, 90))

    # ax2 for Southern Hemisphere
    ax2 = fig.add_subplot(1, 2, 2, projection=ccrs.Orthographic(180, -90))

    img, crs, extent, origin, dt = aurora_forecast()

    for ax in [ax1, ax2]:
        ax.coastlines(zorder=3)
        ax.stock_img()
        ax.gridlines()
        ax.add_feature(Nightshade(dt))
        ax.imshow(img,
                  vmin=0,
                  vmax=100,
                  transform=crs,
                  extent=extent,
                  origin=origin,
                  zorder=2,
                  cmap=aurora_cmap())

    plt.show()
def plot_poles(pos_ecf,
               fig=None,
               axarr=None,
               show_night=True,
               date=None,
               show_aurora=True):

    if axarr is None:
        if fig is None:
            fig = plt.figure(figsize=(10, 5))

        # We choose to plot in an Orthographic projection as it looks natural
        # and the distortion is relatively small around the poles where
        # the aurora is most likely.

        # ax1 for Northern Hemisphere
        ax1 = fig.add_subplot(1, 2, 1, projection=ccrs.Orthographic(0, 90))

        # ax2 for Southern Hemisphere
        ax2 = fig.add_subplot(1, 2, 2, projection=ccrs.Orthographic(180, -90))
    else:
        ax1, ax2 = axarr

        img, crs, extent, origin, dt = aurora_forecast()

    lat, long = ecf_to_latlon(pos_ecf)

    if show_aurora:
        img, crs, extent, origin, dt = aurora_forecast()

    for ax in [ax1, ax2]:

        ax.coastlines(zorder=3)
        ax.stock_img()
        ax.gridlines()

        ax.plot(long.deg, lat.deg, transform=ccrs.Geodetic())

        if show_night:
            if date is None:
                date = datetime(2020, 6, 15, 12)

            ax.set_title("Night time shading for {}".format(date))

            ax.add_feature(Nightshade(date, alpha=0.2))

        if show_aurora:
            ax.imshow(
                img,
                vmin=0,
                vmax=100,
                transform=crs,
                extent=extent,
                origin=origin,
                zorder=2,
                cmap=aurora_cmap(),
            )

    return ax1, ax2
Exemplo n.º 10
0
    def _plot_plate_carree_projection(latitude_sat, longitude_sat,
                                      lat_footprint, lon_footprint, epoch):
        """This method plots the satellite track and footprint in the Plate Carree projection.

        INPUT:
        ------
        latitude_sat    =   vector of latitudes of the satellite. It must be of the same size of longitude_sat.  [deg]
        longitude_sat   =   vector of longitudes of the satellite. It must be of the same size of latitude_sat. [deg]
        lat_footprint   =   vector of latitudes of the boundary of the satellite footprint. [deg]
                            It must be of the same size of lon_footprint.
        lon_footprint   =   vector of longitudes of the boundary of the satellite footprint. [deg]
                            It must be of the same size of lat_footprint.
        epoch           =   epoch to display the nightshade on the map. It must be of type datetime.
        """
        # The longitude array is cut in two piece according to positive values and negative.
        # Positive longitude values will be plotted separately from the negative one.
        longitude_positive = np.ma.masked_where(longitude_sat < 0,
                                                longitude_sat)
        longitude_negative = np.ma.masked_where(longitude_sat >= 0,
                                                longitude_sat)

        # The longitude array is cut in two piece according to positive values and negative.
        # Positive longitude values will be plotted separately from the negative one.
        longitude_footprint_positive = np.ma.masked_where(
            lon_footprint < 0, lon_footprint)
        longitude_footprint_negative = np.ma.masked_where(
            lon_footprint >= 0, lon_footprint)
        plt.figure()
        ax = plt.axes(projection=ccrs.PlateCarree())
        ax.coastlines()
        ax.set_global()
        ax.gridlines()
        ax.add_feature(Nightshade(epoch, alpha=0.4))
        ax.set_xticks([-180, -120, -60, 0, 60, 120, 180],
                      crs=ccrs.PlateCarree())
        ax.set_yticks([-90, -60, -30, 0, 30, 60, 90], crs=ccrs.PlateCarree())
        lon_formatter = LongitudeFormatter(dateline_direction_label=True)
        lat_formatter = LatitudeFormatter()
        ax.xaxis.set_major_formatter(lon_formatter)
        ax.yaxis.set_major_formatter(lat_formatter)
        ax.plot(longitude_positive, latitude_sat, color='#1f77b4', linewidth=2)
        ax.plot(longitude_negative, latitude_sat, color='#1f77b4', linewidth=2)
        ax.plot(longitude_footprint_positive,
                lat_footprint,
                color='#ff7f0e',
                linewidth=2)
        ax.plot(longitude_footprint_negative,
                lat_footprint,
                color='#ff7f0e',
                linewidth=2)
        ax.plot(longitude_sat[0],
                latitude_sat[0],
                'h',
                color='#1e1596',
                markersize=8)
Exemplo n.º 11
0
def is_light(lons, lats, dtime, night=None):
    """
    Tests whether or not arrays of longitudes and latitudes are dark.
    - lons = longitudes, array
    - lats = latitudes, array
    - dtime = datetime instance
    - night = Nightshade instance if you have one, otherwise one will be made
    """
    if night is None:
        night = Nightshade(dtime)
    dark_poly = list(night.geometries())[0]
    mesh_lons, mesh_lats = np.meshgrid(lons, lats)
    # check if each pair of points are inside the dark polygon
    result = np.empty_like(mesh_lons, dtype=int)
    for index, lon in np.ndenumerate(mesh_lons):
        lat = mesh_lats[index]
        # convert coordinate systems to the dark_poly's coords
        x, y = night.crs.transform_point(lon, lat, c.lonlat)
        light = not dark_poly.contains(shapely.geometry.Point(x, y))
        result[index] = light
    return result
Exemplo n.º 12
0
def GlobePlotter(solarlat, solarlon, lattrace, lontrace):
    midlat = np.mean(lattrace)
    midlon = np.mean(lontrace)
    projection = ccrs.Orthographic(midlon, midlat)
    ax = plt.axes(projection=projection)
    file_location = path.abspath(path.dirname(__file__))
    path_to_pic = file_location + '/images/2k_mars.jpg'
    source_proj = ccrs.PlateCarree()
    ax.imshow(imread(path_to_pic), origin='upper', transform=source_proj,
              extent=[-180, 180, -90, 90])

    # plot the ground feature labels
    df = pd.read_csv('mars.csv', encoding='latin-1')
    df.sort_values(by=["Diameter"], inplace=True, ascending=False)
    minlen = 30    # plot only the largest 30 objects on the surface of mars. Maybe update to the the best known
    df = df.head(min(minlen, len(df)))
    for index, row in df.iterrows():
        text = row['Clean_Feature_Name']
        x, y, s = row['Center_Longitude'], row['Center_Latitude'], row['Diameter']

        ax.text(x, y, text, transform=ccrs.PlateCarree(),
                ha='left', va='center', fontsize=8, color='#ebc334')
        ax.scatter(x, y, transform=ccrs.PlateCarree(),
                   s=10, color='#ebc334', edgecolor='None', lw=0)

    # adjusting the gridlines to fit the occtrace location [10 MIGHT BE TO COARSE]
    # STILL NEED BETTER SOLUTION
    minlat = (np.floor(np.min(lattrace)/10))*10
    maxlat = (np.ceil(np.max(lattrace)/10))*10
    minlon = (np.floor(np.min(lontrace)/10))*10
    maxlon = (np.ceil(np.max(lontrace)/10))*10
    track = sgeom.LineString(zip(lontrace, lattrace))
    ax.add_geometries([track], source_proj,
                      edgecolor='#C852C8', linewidth=8, alpha=0.5, facecolor='none')
    gl = ax.gridlines(crs=ccrs.PlateCarree(), linewidth=2,
                      color='k', alpha=0.2, linestyle='--', draw_labels=True)
    gl.top_labels = False
    gl.left_labels = False
    gl.right_labels = False
    gl.xlines = True
    gl.ylocator = mticker.FixedLocator(
        list(np.arange(int(minlat), int(maxlat), 10)))
    gl.xlocator = mticker.FixedLocator(
        list(np.arange(int(minlon), int(maxlon), 10)))
    gl.xlabel_style = {'color': 'k'}

    # <<<< this involves a custom nightshade function, go into the cartopy libs and edit to include lat lon
    ax.add_feature(Nightshade(solarlat, solarlon))

    # plot occultation track
    ax.add_geometries([track], source_proj,
                      edgecolor='#C852C8', linewidth=8, alpha=0.5, facecolor='none')
    plt.show()
Exemplo n.º 13
0
    def __init__(self, metric_name, date, decorations=True, basemaps=True, alpha=0.35, centered=None):
        self.metric_name = metric_name
        self.date = date
        self.decorations = decorations
        self.basemaps = basemaps
        self.plotalpha = alpha

        if centered is None:
            self.proj = ccrs.PlateCarree()
            figsize=(16,24)
        else:
            self.proj = ccrs.AzimuthalEquidistant(centered[0], centered[1])
            figsize=(12,12)

        self.fig = plt.figure(figsize=figsize)
        self.ax = plt.axes(
            projection=self.proj,
            frame_on=self.decorations,
            facecolor='white',
        )
        self.ax.spines['geo'].set_edgecolor('#666')
        self.ax.set_global()

        if self.decorations:
            if centered is None:
                self.ax.grid(True, visible=True, linewidth=.5, color='black', alpha=0.25, linestyle='--')
                self.ax.set_xticks([-180, -160, -140, -120,-100, -80, -60,-40,-20, 0, 20, 40, 60,80,100, 120,140, 160,180], crs=ccrs.PlateCarree())
                self.ax.set_yticks([-80, -60,-40,-20, 0, 20, 40, 60,80], crs=ccrs.PlateCarree())
            else:
                self.ax.gridlines(
                    linewidth=.5,
                    color='black',
                    alpha=0.25,
                    linestyle='--',
                    xlocs=[-180, -160, -140, -120,-100, -80, -60,-40,-20, 0, 20, 40, 60,80,100, 120,140, 160,180],
                    ylocs=[-80, -60,-40,-20, 0, 20, 40, 60,80],
                )
        else:
            self.ax.axis(False)
            self.ax.outline_patch.set_visible(False)
            self.ax.background_patch.set_visible(False)
            self.ax.set_xmargin(0)
            self.ax.set_ymargin(0)

        if basemaps:
            self.ax.add_feature(cartopy.feature.NaturalEarthFeature('physical', 'land', '110m',
                edgecolor='face',
                facecolor=np.array((0xdd,0xdd,0xcc))/256.,
                zorder=-1
                )
            )

            self.ax.add_feature(Nightshade(self.date, alpha=0.08))
Exemplo n.º 14
0
def get_light_mask(dtime):
    """
    Get 2D array associated with MERRA grid points, 1 = light 0 = dark,
    at a given time (dtime = datetime instance)
    """
    light_mask_file = dtime.strftime(c.light_mask_format)
    if not exists(light_mask_file):
        print("Creating light_mask, this might take 30 seconds")
        # this is the polygon that is the "shady" area
        night = Nightshade(dtime)
        # get all points not within the dark_poly
        light_mask = is_light(c.lons, c.lats, dtime, night)
        # save result to file
        np.save(light_mask_file, light_mask)
    return np.load(light_mask_file)
Exemplo n.º 15
0
def plot_planisphere(pos_ecf,
                     fig=None,
                     ax=None,
                     show_night=True,
                     date=None,
                     show_aurora=True):

    if ax is None:
        if fig is None:
            fig = plt.figure(figsize=(10, 5))
        ax = fig.add_subplot(1, 1, 1, projection=ccrs.Robinson())

    # make the map global rather than have it zoom in to
    # the extents of any plotted data
    # ax.set_global()

    ax.stock_img()
    ax.coastlines()
    ax.gridlines()

    lat, long = ecf_to_latlon(pos_ecf)
    ax.plot(long.deg, lat.deg, transform=ccrs.Geodetic())

    if show_night:
        if date is None:
            date = datetime(2020, 6, 15, 12)

        ax.set_title("Night time shading for {}".format(date))

        ax.add_feature(Nightshade(date, alpha=0.2))

    if show_aurora:
        img, crs, extent, origin, dt = aurora_forecast()
        ax.imshow(
            img,
            vmin=0,
            vmax=100,
            transform=crs,
            extent=extent,
            origin=origin,
            zorder=2,
            cmap=aurora_cmap(),
        )

    return ax
Exemplo n.º 16
0
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Sat Dec 29 13:03:47 2018

@author: ahmed
"""

import datetime
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
from cartopy.feature.nightshade import Nightshade


fig = plt.figure(figsize=(10, 5))
ax = fig.add_subplot(1, 1, 1, projection=ccrs.PlateCarree())

date = datetime.datetime(2019, 1, 13, 11)

ax.set_title('Night time shading for {}'.format(date))
ax.stock_img()
ax.add_feature(Nightshade(date, alpha=0.2))
plt.savefig("cartopy1.png"); plt.savefig("cartopy1.pdf")
plt.show()
Exemplo n.º 17
0
def europe_canada_predstorm(world_image,dt,counter,colormap_input):


 plt.close('all')
 #Night map from VIIRS
 #https://wiki.earthdata.nasa.gov/display/GIBS/GIBS+Available+Imagery+Products#expand-EarthatNight4Products
 #nightmap = 'https://map1c.vis.earthdata.nasa.gov/wmts-geo/wmts.cgi'


 #define extent of the produced world maps - defined as: west east south north
 mapextent=[-180,180,-90,90]   


 #not so good: layer='VIIRS_Black_Marble'
 #better but takes time
 #layer = 'VIIRS_CityLights_2012'

 
 #need to set alpha linearly increasing in the colormap
 cmap = plt.get_cmap(colormap_input)  # Choose colormap
 my_cmap = cmap(np.arange(cmap.N))  # Get the colormap colors
 my_cmap[:,-1] = np.linspace(0.3, 1, cmap.N)  # Set alpha
 my_cmap = ListedColormap(my_cmap) # Create new colormap


 land_50m = carfeat.NaturalEarthFeature('physical', 'land', '50m',
                                        edgecolor='k',
                                        facecolor=carfeat.COLORS['land'])
 ocean_50m = carfeat.NaturalEarthFeature('physical', 'ocean', '50m',
                                        edgecolor='k',
                                        facecolor='steelblue')#carfeat.COLORS['water'])                                        
 provinces_50m = carfeat.NaturalEarthFeature('cultural',
                                             'admin_1_states_provinces_lines',
                                             '50m',
                                             facecolor='none',edgecolor='black')
 crs=ccrs.PlateCarree()



 #16/9 ration for full hd output
 fig = plt.figure(2,figsize=[16, 9],dpi=100) 
 fig.set_facecolor('black') 
 plt.cla()

 # ax1 Europe
 ax1 = plt.subplot(1, 2, 2, projection=ccrs.Orthographic(0, 60),position=[0.51,0.05,0.48,0.9])#[left, bottom, width, height]
 # ax2 northern America
 ax2 = plt.subplot(1, 2, 1, projection=ccrs.Orthographic(-100, 60), position=[0.01,0.05,0.48,0.9])

 #define map extents
 canada_east = -65
 canada_west = -135 
 canada_north = 75
 canada_south = 20

 europe_east = 50
 europe_west = -20
 europe_north = 75
 europe_south = 30


 #plot one axis after another
 for ax in [ax1, ax2]:

    #ax.gridlines(linestyle='--',alpha=0.2,color='white')
    #ax.coastlines(alpha=0.5,zorder=3)

    #ax.add_feature(carfeat.LAND,zorder=2,alpha=1)
    #ax.add_feature(land_50m, color='darkgreen')
    #ax.add_feature(land_50m, color='darkslategrey')
    ax.add_feature(land_50m, color='dimgrey')
    ax.add_feature(provinces_50m,alpha=0.5)#,zorder=2,alpha=0.8)

  
    #ax.add_feature(carfeat.COASTLINE)#,zorder=2,alpha=0.5)
    #ax.add_feature(carfeat.OCEAN,color='mediumslateblue')#,zorder=2,alpha=1)
    ax.add_feature(ocean_50m, color='darkblue')

    #ax.add_feature(carfeat.RIVERS)#,zorder=2,alpha=0.8)
    ax.add_feature(carfeat.LAKES,color='darkblue')#,zorder=2,alpha=1) color navy?
    
    ax.add_feature(carfeat.BORDERS, alpha=0.5)#,zorder=2,alpha=0.5)
  
    ax.add_feature(Nightshade(dt))
  
    #ax.stock_img()
    
    #ax.add_wmts(nightmap, layer)
  
    ax.imshow(world_image, vmin=0.001, vmax=5, transform=crs, extent=mapextent, origin='lower', zorder=3, alpha=0.8, cmap=my_cmap)
    
    if ax == ax1: ax.set_extent([europe_west, europe_east, europe_south, europe_north])
    if ax == ax2: ax.set_extent([canada_west, canada_east, canada_south, canada_north])

 fig.text(0.01,0.92,'PREDSTORM aurora forecast   '+dt.strftime('%Y-%m-%d %H:%M UT' ), color='white',fontsize=15)
 fig.text(0.99,0.02,'C. Möstl / IWF-helio, Austria', color='white',fontsize=8,ha='right')

 
 #save as image with timestamp in filename
 plot_europe_canada_filename='results/forecast_europe_canada/predstorm_aurora_real_'+dt.strftime("%Y_%m_%d_%H%M")  +'.jpg'
 fig.savefig(plot_europe_canada_filename,dpi=120,facecolor=fig.get_facecolor())


 #save as movie frame
 framestr = '%05i' % (counter)  
 fig.savefig('results/frames_europe_canada/aurora_'+framestr+'.jpg',dpi=120,facecolor=fig.get_facecolor())
 #plt.show()
 print('Saved image:  ',plot_europe_canada_filename)
Exemplo n.º 18
0
def plot_map_and_stations(fig,
                          gridspec,
                          station_locations,
                          station_names,
                          station_plot_dict,
                          region_corners=None,
                          ss_location=None,
                          date=None):
    map_ax = fig.add_subplot(gridspec,
                             projection=ccrs.NearsidePerspective(
                                 -95, 57, 15000000))
    map_ax.stock_img()
    # Plot the border of region
    if region_corners is not None:
        map_ax.plot(np.linspace(region_corners[0][0], region_corners[1][0],
                                10),
                    np.ones(10) * region_corners[0][1],
                    '--',
                    color='gray',
                    transform=ccrs.PlateCarree())

        map_ax.plot(np.ones(10) * region_corners[1][0],
                    np.linspace(region_corners[0][1], region_corners[1][1],
                                10),
                    '--',
                    color='gray',
                    transform=ccrs.PlateCarree())

        map_ax.plot(np.linspace(region_corners[0][0], region_corners[1][0],
                                10),
                    np.ones(10) * region_corners[1][1],
                    '--',
                    color='gray',
                    transform=ccrs.PlateCarree())

        map_ax.plot(np.ones(10) * region_corners[0][0],
                    np.linspace(region_corners[0][1], region_corners[1][1],
                                10),
                    '--',
                    color='gray',
                    transform=ccrs.PlateCarree())

    # plot all stations
    map_ax.plot(station_locations[:, 0],
                station_locations[:, 1],
                '.',
                color='black',
                transform=ccrs.PlateCarree())
    # plot special stations
    for entry in station_plot_dict:
        map_ax.plot(station_locations[entry['indices'], 0],
                    station_locations[entry['indices'], 1],
                    '.',
                    color=entry['color'],
                    transform=ccrs.PlateCarree(),
                    label=entry['name'])
        if entry['station names']:
            for j in entry['indices']:
                map_ax.text(station_locations[j, 0] - 1,
                            station_locations[j, 1] - 1,
                            station_names[j],
                            horizontalalignment='right',
                            transform=ccrs.PlateCarree())

    map_ax.legend()

    if ss_location is not None:
        map_ax.plot(ss_location[0],
                    ss_location[1],
                    'rx',
                    transform=ccrs.PlateCarree())

    if date is not None:
        map_ax.add_feature(Nightshade(date, alpha=0.2))
Exemplo n.º 19
0
def plot_data_globe_colour(station_readings,
                           t,
                           list_of_stations=None,
                           ortho_trans=(0, 0)):
    if np.all(list_of_stations == None):
        list_of_stations = station_readings.station
    if np.all(ortho_trans == (0, 0)):
        ortho_trans = svg.auto_ortho(list_of_stations)

    station_coords = svg.csv_to_coords()
    num_stations = len(list_of_stations)
    x = np.zeros(num_stations)
    y = np.zeros(num_stations)
    u = np.zeros(num_stations)
    v = np.zeros(num_stations)
    i = 0

    for station in list_of_stations:
        x[i] = station_coords.longitude.loc[dict(station=station)]
        y[i] = station_coords.latitude.loc[dict(station=station)]
        u[i] = station_readings.measurements.loc[dict(station=station,
                                                      time=t,
                                                      component="E")]
        v[i] = station_readings.measurements.loc[dict(station=station,
                                                      time=t,
                                                      component="N")]
        i += 1

    fig = plt.figure(figsize=(20, 20))
    ax = fig.add_subplot(1,
                         1,
                         1,
                         projection=ccrs.Orthographic(
                             ortho_trans[0], ortho_trans[1]))  #(long, lat)
    ax.add_feature(cfeature.OCEAN, zorder=0)
    ax.add_feature(cfeature.LAND, zorder=0, edgecolor='grey')
    ax.add_feature(cfeature.BORDERS, zorder=0, edgecolor='grey')
    ax.add_feature(cfeature.LAKES, zorder=0)
    ax.add_feature(Nightshade(t))
    ax.set_global()
    ax.gridlines()

    ax.scatter(x, y, color="k", transform=ccrs.Geodetic())  #plots stations

    colours = np.ones((num_stations, 3))

    for i in range(num_stations):
        colours[i, 0] = station_coords.longitude.loc[dict(
            station=list_of_stations[i])] / 360
        colours[i, 2] = (station_coords.latitude.loc[dict(
            station=list_of_stations[i])] - 10) / 80

    colours = plc.hsv_to_rgb(colours)

    ax.quiver(
        x,
        y,
        u,
        v,
        transform=ccrs.PlateCarree(),  #plots vector data
        width=0.002,
        color=colours)

    mytime = t.strftime('%Y.%m.%d %H:%M')

    plt.title("%s" % mytime, fontsize=30)

    return fig
Exemplo n.º 20
0
def main():
    SPH_ORDER = 3
    SPH_WEIGHT = 0.8
    RESIDUAL_WEIGHT = 0.9

    plt.clf()

    with urllib.request.urlopen(os.getenv("METRICS_URI")) as url:
        data = json.loads(url.read().decode())

    df = json_normalize(data)

    #delete low confidence measurements
    df = df.drop(df[pd.to_numeric(df.cs) == 0].index)
    df = df.drop(df[df[metric] == 0].index)
    df = df.dropna(subset=[metric])

    #filter out data older than 1hr
    age = (dt.datetime.now() -
           dt.timedelta(minutes=60)).strftime('%Y-%m-%d %H:%M')
    df = df.loc[df['time'] > age]

    df['time'] = pd.to_datetime(df.time)
    df['time'] = df['time'].dt.strftime('%Y-%m-%d %H:%M')

    df[[metric]] = df[[metric]].apply(pd.to_numeric)
    df[['station.longitude']] = df[['station.longitude']].apply(pd.to_numeric)
    df[['station.latitude']] = df[['station.latitude']].apply(pd.to_numeric)
    df['longitude_radians'] = df['station.longitude'] * np.pi / 180.
    df['latitude_radians'] = (df['station.latitude'] + 90) * np.pi / 180.
    df[['cs']] = df[['cs']].apply(pd.to_numeric)
    df.loc[df['cs'] == -1, 'cs'] = 80
    df[['cs']] = df[['cs']] / 100.
    df['transformed'] = np.log(df[metric])

    df = df.dropna(subset=[metric])
    df.loc[df['station.longitude'] > 180,
           'station.longitude'] = df['station.longitude'] - 360

    df.sort_values(by=['station.longitude'], inplace=True)

    sph = []
    alpha = []
    for n in range(SPH_ORDER):
        for m in range(0 - n, n + 1):
            sph.append(
                real_sph(m, n, df['longitude_radians'].values,
                         df['latitude_radians'].values).reshape((-1, 1)))
            alpha.append(0 if n == 0 else 0.005)
    sph = np.hstack(sph)

    wls_model = sm.WLS(df['transformed'].values, sph, df['cs'].values)
    wls_result = wls_model.fit_regularized(alpha=np.array(alpha), L1_wt=0.6)
    coeff = wls_result.params

    numcols, numrows = 360, 180
    loni = np.linspace(-180, 180, numcols)
    lati = np.linspace(-90, 90, numrows)

    theta = loni * np.pi / 180.
    phi = (lati + 90) * np.pi / 180.

    zi = np.zeros((len(phi), len(theta)))
    theta, phi = np.meshgrid(theta, phi)

    df['pred'] = np.zeros(len(df))

    coeff_idx = 0
    for n in range(SPH_ORDER):
        for m in range(0 - n, n + 1):
            sh = real_sph(m, n, theta, phi)
            weight = 1 if n == 0 else SPH_WEIGHT
            zi = zi + weight * coeff[coeff_idx] * sh
            df['pred'] = df['pred'] + weight * np.real(
                coeff[coeff_idx] *
                real_sph(m, n, df['longitude_radians'].values,
                         df['latitude_radians'].values))
            coeff_idx = coeff_idx + 1

    df['residual'] = df['transformed'] - df['pred']
    #plot data

    loni, lati = np.meshgrid(loni, lati)
    x, y, z = sph_to_xyz(df['station.longitude'].values,
                         df['station.latitude'].values)
    t = df['residual'].values

    stdev = 0.7 - 0.5 * df['cs']

    gp = rbf.gauss.gpiso(rbf.basis.se, (0.0, 0.7, 0.8))
    gp_cond = gp.condition(np.vstack((x, y, z)).T, t, sigma=stdev)

    xxi, yyi, zzi = sph_to_xyz(loni, lati)
    xyz = np.array([xxi.flatten(), yyi.flatten(), zzi.flatten()]).T
    resi, sd = gp_cond.meansd(xyz)
    resi = resi.reshape(xxi.shape)
    sd = sd.reshape(xxi.shape)

    zi = zi + RESIDUAL_WEIGHT * resi
    zi = np.exp(zi)

    fig = plt.figure(figsize=(16, 24))
    ax = plt.axes(projection=ccrs.PlateCarree())

    levels = 16
    cmap = plt.cm.get_cmap('viridis')
    cmap.set_under(cmap(1e-5))
    cmap.set_over(cmap(1 - 1e-5))
    norm = matplotlib.colors.Normalize(clip=False)

    if metric == 'mufd':
        levels = [
            3, 3.5, 4, 4.6, 5.3, 6.1, 7, 8.2, 9.5, 11, 12.6, 14.6, 16.9, 19.5,
            22.6, 26, 30
        ]
        norm = matplotlib.colors.LogNorm(3.5, 30, clip=False)

    mycontour = plt.contourf(loni,
                             lati,
                             zi,
                             levels,
                             cmap=cmap,
                             extend='both',
                             transform=ccrs.PlateCarree(),
                             alpha=0.3,
                             norm=norm)

    ax.add_feature(
        cartopy.feature.NaturalEarthFeature('physical',
                                            'land',
                                            '110m',
                                            edgecolor='face',
                                            facecolor=np.array(
                                                (0xdd, 0xdd, 0xcc)) / 256.,
                                            zorder=-1))
    ax.set_global()
    ax.add_feature(Nightshade(date, alpha=0.08))

    ax.grid(linewidth=.5, color='black', alpha=0.25, linestyle='--')
    ax.set_xticks([
        -180, -160, -140, -120, -100, -80, -60, -40, -20, 0, 20, 40, 60, 80,
        100, 120, 140, 160, 180
    ],
                  crs=ccrs.PlateCarree())
    ax.set_yticks([-80, -60, -40, -20, 0, 20, 40, 60, 80],
                  crs=ccrs.PlateCarree())

    for index, row in df.iterrows():
        lon = float(row['station.longitude'])
        lat = float(row['station.latitude'])
        alpha = 0.2 + 0.6 * row['cs']
        ax.text(lon,
                lat,
                int(row[metric] + 0.5),
                fontsize=9,
                ha='left',
                transform=ccrs.PlateCarree(),
                alpha=alpha,
                bbox={
                    'boxstyle': 'circle',
                    'alpha': alpha - 0.1,
                    'color': cmap(norm(row[metric])),
                    'mutation_scale': 0.5,
                })

    CS2 = plt.contour(mycontour,
                      linewidths=.5,
                      alpha=0.66,
                      levels=mycontour.levels[1::1])

    prev = None
    levels = []
    for lev in CS2.levels:
        if prev is None or '%.0f' % (lev) != '%.0f' % (prev):
            levels.append(lev)
            prev = lev

    plt.clabel(CS2,
               levels,
               inline=True,
               fontsize=10,
               fmt='%.0f',
               use_clabeltext=True)

    # Make a colorbar for the ContourSet returned by the contourf call.
    cbar = plt.colorbar(mycontour,
                        fraction=0.03,
                        orientation='horizontal',
                        pad=0.02,
                        format=matplotlib.ticker.ScalarFormatter())
    #cbar.set_label('MHz') #TODO add unit
    cbar.add_lines(CS2)

    plt.title(metric + ' ' + str(now))

    #    df = df[['station.name', 'time', metric, 'cs', 'altitude', 'station.longitude', 'station.latitude']]

    #    df = df.round(2)

    #    the_table = table(ax, df,
    #          bbox=[0,-1.25,1,1],
    #          cellLoc = 'left',)

    #    for key, cell in the_table.get_celld().items():
    #        cell.set_linewidth(.25)

    plt.tight_layout()
    plt.savefig('/output/{}.png'.format(metric), dpi=180, bbox_inches='tight')
    plt.savefig('/output/{}.svg'.format(metric), dpi=180, bbox_inches='tight')

    # Convert matplotlib contour to geojson
    """
Exemplo n.º 21
0
place = np.array([0, np.pi / 2., np.pi, 1.5 * np.pi])
lab = ['', 'dawn', 'noon', 'dusk']
plt.xticks(place, lab)  #, )
ax1.set_ylim(0, 10)
ax1.set_xlim(0, 2. * np.pi)

ax1.set_frame_on(False)
#ax1.axes.get_xaxis().set_visible(False)
#ax1.axes.get_yaxis().set_visible(False)

#This will be the geographic plot
ax = fig.add_subplot(1, 2, 2, projection=ccrs.Orthographic(180, -90))
ax.coastlines(zorder=3)
ax.stock_img()
ax.gridlines()
ax.add_feature(Nightshade(dt))

for i in range(len(payload)):
    print('starting to plot payload ', payload[i])
    #Here we are just defining the different colors to be used. This could also be done outside the loop in an array and then use mkrcolor[i] in the plotting portion, This was just an easy way for me to make sure I knew which payload was which color... The program would run faster if done the way mentioned above, but it's pretty quick already. Save to change when doing a larger project.
    if payload[i] == '2I':
        mkrcolor = cdk  #'navy'
        #Make sure we have the right sting. If I were to do this for a longer period of time, the same would need to be done for the month ect....
        if day < 10:
            strday = '0' + np.str(np.int(day))
        else:
            strday = np.str(day)
        #Read in the data and get the relavent data bits.
        payload_ephm = 'data/bar_' + payload[
            i] + '_l2_ephm_201401' + strday + '_v04.cdf'
        data = pycdf.CDF(payload_ephm)
Exemplo n.º 22
0
def plot_ISS(trackdf, nhours_plot=1):

    fig = plt.figure(figsize=(20, 10))

    projection_type = ccrs.PlateCarree()
    ax = fig.add_subplot(1, 1, 1, projection=projection_type)

    ax.coastlines(resolution='50m', linewidth=0.3)

    timestart = trackdf.index[-1] - np.timedelta64(nhours_plot, 'h')
    track = trackdf.iloc[:1000]

    jump_indices = list(track[abs(track['londiff']) > 330].index)

    for i in range(len(jump_indices)):

        if i == 0:
            subtrack = track[:jump_indices[0]]
        else:
            subtrack = track[jump_indices[i - 1]:jump_indices[i]].iloc[1:]

        track_points = sgeom.LineString(zip(subtrack['Lon'], subtrack['Lat']))
        ax.add_geometries([track_points], projection_type,facecolor='none', \
                        edgecolor='r',alpha=0.8)

        #plot the locations as points
        ax.plot(subtrack['Lon'],
                subtrack['Lat'],
                'ko',
                transform=projection_type,
                markersize=0.5)

    #plot the final subtrack
    subtrack = track[jump_indices[i]:].iloc[1:]
    track_points = sgeom.LineString(zip(subtrack['Lon'], subtrack['Lat']))
    ax.add_geometries([track_points], projection_type,facecolor='none', \
                      edgecolor='r',alpha=0.8)
    #plot the locations as points
    ax.plot(subtrack['Lon'],
            subtrack['Lat'],
            'ko',
            transform=projection_type,
            markersize=0.5)

    #Get current location
    current_lon, current_lat = getISSloc()

    ax.plot(current_lon,
            current_lat,
            'bo',
            transform=projection_type,
            markersize=20)

    #Get current time
    date = datetime.utcnow()

    ax.set_title('ISS history and position for {}'.format(date))
    ax.stock_img()
    ax.add_feature(Nightshade(date, alpha=0.2))
    #plt.show()
    plt.savefig('Latest_ISS_plot.pdf', dpi=200)
Exemplo n.º 23
0
#img, crs, extent, origin, dt = aurora_forecast()

fig.set_facecolor((0, 0, 0))

url = 'https://map1c.vis.earthdata.nasa.gov/wmts-geo/wmts.cgi'
layer = 'VIIRS_CityLights_2012'

for ax in [ax1, ax2]:
    ax.coastlines(zorder=3, color='grey', alpha=0.9)
    ax.add_feature(carfeat.BORDERS, zorder=3, alpha=0.9)
    #ax.stock_img()
    #takes long!!
    #ax.add_wmts(url, layer)
    ax.gridlines(alpha=0.3)
    ax.add_feature(Nightshade(dtovation), alpha=0.9)
    #ax.imshow(img, vmin=0, vmax=100, transform=crs,	extent=extent, origin=origin, zorder=2,		cmap=aurora_cmap())
    ax.imshow(pimg,
              vmin=0,
              vmax=100,
              transform=crs,
              extent=extent,
              origin=origin,
              zorder=2,
              cmap=aurora_cmap())

plt.show()
#plt.tight_layout()
fig.savefig('predstorm_aurora_pred_' + dtovation.strftime("%Y_%m_%d_%H%M") +
            '.png',
            dpi=300)
Exemplo n.º 24
0
"""
import pygeode as pyg, numpy as np, pylab as pyl
from cartopy import crs as ccrs
import cartopy
from cartopy.feature.nightshade import Nightshade
from datetime import datetime as dt

lat = pyg.gausslat(60)
lon = pyg.regularlon(120)

x = pyg.sin(2*np.pi * lon / 180.) * pyg.exp(-(lat - 30)**2 / (2*10**2))
y = pyg.sin(2*np.pi * lon / 180.) * pyg.exp(-(lat + 40)**2 / (2*10**2))

pyl.ioff()
prj = dict(central_longitude = 60)
#ax = pyg.plot.CartopyAxes(projection = 'NearsidePerspective', prj_args = prj)

map = dict(projection = 'NearsidePerspective', prj_args = prj)
#map = dict(projection = 'LambertConformal', prj_args = prj)

cl = pyg.cldict(0.1, nozero=True)
ax = pyg.vcontour(x, map = map, **cl)
ax.add_feature(cartopy.feature.OCEAN)
ax.add_feature(Nightshade(dt.utcnow()))
ax.setp(title = '')

pyl.ion()
ax.render(2)

ax.ax.tissot(facecolor='orange', alpha=0.8)
    plt.plot([inv_lon, inv_lon], [inv_lat, inv_lat],
             'bo',
             markersize=radar_marker_size,
             transform=ccrs.Geodetic(),
             label="INV")

    # Add RISR to the map
    plt.plot([risr_lon, risr_lon], [risr_lat, risr_lat],
             'ro',
             markersize=radar_marker_size,
             transform=ccrs.Geodetic(),
             label="RISR",
             zorder=3)

    date_time = datetime.utcnow()
    ax.add_feature(Nightshade(date_time, alpha=0.25))
    # ax.set_title("Night time shading for " + str(date_time) + " UT")

    ax.set_title("One-and-one-half-hop Geometry Check")

    # Try to plot RKN's FoV  # RKN is id 65
    ranges = [0, 100]

    rkn_beam_corners_lats, rkn_beam_corners_lons = radar_fov(65, coords='geo')
    rkn_fan_shape = rkn_beam_corners_lons.shape

    inv_beam_corners_lats, inv_beam_corners_lons = radar_fov(64, coords='geo')
    inv_fan_shape = inv_beam_corners_lons.shape

    # plot all the RKN beam boundary lines
    for beam_line in range(rkn_fan_shape[1]):
Exemplo n.º 26
0
def ovation_global_north(wic,dt,colormap_input,max_level, outputdir,longitude_bound,equatorial_bound):
 '''
 plots the ovation aurora on the northern hemisphere from a polar view, makes movie frames
 wic is a world image cube with ovation results 512x1024
 dt are the datetimes for each frame
 colormap_input is the colormap
 max_level is the maximum level for the colorbar
 '''
 #plotting parameters
 #-100 for North America, +10 or 0 for Europe
 global_plot_longitude=-100
 #global_plot_longitude=0
 global_plot_latitude=90


 provinces_50m = carfeat.NaturalEarthFeature('cultural',
                                             'admin_1_states_provinces_lines',
                                             '50m',
                                             facecolor='none',edgecolor='black')



 #define extent of the produced world maps - defined as: west east south north
 mapextent=[-180,180,-90,90]   
 
 #need to set alpha linearly increasing in the colormap so that it blends into background for 
 #small values
 cmap = plt.get_cmap(colormap_input)  # Choose colormap
 my_cmap = cmap(np.arange(cmap.N))  # Get the colormap colors
 my_cmap[:,-1] = np.linspace(0, 1, cmap.N)  # Set alpha
 my_cmap = ListedColormap(my_cmap) # Create new colormap

 crs=ccrs.PlateCarree()

 fig = plt.figure(2,figsize=[12, 12],dpi=80) 
 fig.set_facecolor('black') 
 fig.text(0.99,0.01,'C. Möstl / IWF-helio, Austria', color='white',fontsize=10,ha='right',va='bottom')
 
 
 ax = plt.subplot(1, 1, 1, projection=ccrs.Orthographic(global_plot_longitude, global_plot_latitude))

 ax.background_patch.set_facecolor('k')    
 
 
 gl=ax.gridlines(linestyle='--',alpha=0.5,color='white') #make grid
 gl.n_steps=100   #make grid finer
 ax.stock_img()  
 
 #ax.coastlines('50m',color='black',alpha=0.5)
 ax.coastlines('50m',color='white',alpha=0.9)
 ax.add_feature(provinces_50m,alpha=0.2)    #,zorder=2,alpha=0.8)
 ax.add_feature(carfeat.BORDERS, alpha=0.2) #,zorder=2,alpha=0.5)
  

 
 #these are calls that create the first object to be removed from the plot with each frame
 txt=fig.text(0.5,0.92,'')
 border=ax.add_feature(Nightshade(dt[0]))  #add day night border
 img=ax.imshow(wic[:,:,0])
 bound_e=ax.plot(0,color='k') #equatorial boundary
 bound_v=ax.plot(0,color='k') #equatorial boundary

 for i in np.arange(0,np.size(dt)):

     print('global movie frame',i)
 
     #plt.cla()  #clear axes
     txt.set_visible(False)  #clear previous plot title
     #plot title with time
     txt=fig.text(0.5,0.92,'PREDSTORM aurora  '+dt[i].strftime('%Y-%m-%d %H:%M UT'), color='white',fontsize=15, ha='center')
     img.remove()     #remove previous wic
     border.remove()  #remove previous nightshade
     bound_e[0].remove() #remove equatorial boundary
     bound_v[0].remove() #remove view line
     
     border=ax.add_feature(Nightshade(dt[i]))  #add day night border
     img=ax.imshow(wic[:,:,i], vmin=0.01, vmax=max_level, transform=crs, extent=mapextent, origin='lower', zorder=3, alpha=0.8, cmap=my_cmap) #aurora
     bound_e=ax.plot(longitude_bound,equatorial_bound[i,:],transform=crs,color='k',alpha=0.8) #equatorial boundary
     
     #***cut view line at longitudes which are in daylight
     
     bound_v=ax.plot(longitude_bound,equatorial_bound[i,:]-8,transform=crs,color='r',linestyle='--',alpha=0.8) #viewing line after Case et al. 2016


  
     #save as image with timestamp in filename
     #plot_Nhemi_filename='results/forecast_global/predstorm_aurora_real_Nhemi_'+dt.strftime("%Y_%m_%d_%H%M")  +'.jpg'
     #fig.savefig(plot_Nhemi_filename,dpi=150,facecolor=fig.get_facecolor())
     
     
     #save as movie frame
     framestr = '%05i' % (i)  
     fig.savefig('results/'+outputdir+'/frames_global/aurora_'+framestr+'.jpg',dpi=150,facecolor=fig.get_facecolor())
Exemplo n.º 27
0
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
Exemplo n.º 28
0
def process_gcn(payload, root):
    if write_event:
        event_log = open(logfile, 'a+')
    # Respond only to 'test' events.
    # VERY IMPORTANT! Replace with the following code
    # to respond to only real 'observation' events.
    print("starting process")
    print(datetime.utcnow())
    if write_event:
        event_log.write("starting process")
        event_log.write('\n')
        event_log.write(root.attrib['role'])
        event_log.write('\n')
    print(root.attrib['role'])

    """ Uncomment when we only want to do real observations
    if root.attrib['role'] != 'observation':
       return
    """

    # Read all of the VOEvent parameters from the "What" section.

    params = {elem.attrib['name']:
                  elem.attrib['value']
              for elem in root.iterfind('.//Param')}

    # Respond only to 'CBC' events. Change 'CBC' to "Burst'
    # to respond to only unmodeled burst events.
    print(params['Group'])
    if write_event:
        event_log.write(params['Group'])
        event_log.write('\n')
    if params['Group'] != 'CBC':
        print('not CBC')
        return
    if params['AlertType'] != 'Preliminary':
        print('not Preliminary')
        return
    if 'Pkt_Ser_Num' in params:  # Test events send same event twice, only choose first one.
        check = float(params['Pkt_Ser_Num'])
        if check > 1.1:
            return

    """ COMPLETE TO DEFINE WHICH EVENTS WE ARE LOOKING FOR
    if 'BNS' in params:
       check = float(params['BNS'])
       if  check < 50.0:
          print("not BNS event, skipping")
          return
    else:
       print("not BNS event, skipping")
       return
    """
    # Print all parameters.
    for key, value in params.items():
        print(key, '=', value)
        if write_event:
            event_log.writelines(str(key + '=' + value))

    if 'skymap_fits' in params:
        # Read the HEALPix sky map and the FITS header.i
        skymap, header = hp.read_map(params['skymap_fits'], h=True, verbose=False)
        header = dict(header)

        # Print some values from the FITS header.
        print('Distance =', header['DISTMEAN'], '+/-', header['DISTSTD'])
        if write_event:
            event_log.writelines('Distance =' + str(header['DISTMEAN']) + '+/-' + str(header['DISTSTD']))
            event_log.write('\n')

        # write event information to SQL
        datadict = {'gracedb_id': [params['GraceID']], 'link': [params['EventPage']], 'dist': [header['DISTMEAN']],
                    'dist_err': [header['DISTSTD']]}
        sql_engine = sql.create_engine(connect_string)
        headers = ['gracedb_id', 'link', 'dist', 'dist_err']
        dtypes = {'gracedb_id': 'str', 'link': 'str', 'dist': 'float64', 'dist_err': 'float64'}
        df = pd.DataFrame.from_dict(datadict)
        df.to_sql('events', sql_engine, if_exists='append', index=False)

        # get event ID back
        query = "select * from events ORDER BY 'ID' DESC"
        df = pd.read_sql_query(query, sql_engine)
        event = df['ID'].iloc[-1]

        credible_levels = find_greedy_credible_levels(skymap)

        if send_slack:
            slackmsg = ""
            for key, value in params.items():
                slackmsg = slackmsg + str(key) + '=' + str(value) + '\n'

            slack_client.chat_postMessage(channel=SLACK_CHANNEL, text=slackmsg)
        # get df of galaxies from SQL
        query = "select * from galaxies"
        galaxies = pd.read_sql_query(query, sql_engine)
        gal_ipix = getPixel(skymap, galaxies['ra'], galaxies['dec'])
        """
        offset = ephem.Observer()
        offset.lat = '0.0'
        offset.long = '180'
        offset.date = datetime.utcnow()
        offangle = float(offset.sidereal_time() * 180 / np.pi)
        """
        if plot_map:
            #ax = plt.axes(projection=ccrs.Mollweide(central_longitude=-1 * offangle))
            ax = plt.axes(projection=ccrs.Mollweide())
            ax.stock_img()

        galaxies['credible'] = credible_levels[gal_ipix]
        banana_galaxies = galaxies[(galaxies.credible <= prob_check)]
        banana_galaxies.sort_values(by=['credible'], inplace=True)

        #get list of observatories from SQL
        query = "select * from observers"
        observatories = pd.read_sql_query(query, sql_engine)
        #Find Sun RA/DEC
        sun = ephem.Sun()
        #setup pyephem observer
        telescope = ephem.Observer()
        telescope.date = datetime.utcnow()
        #create a copy of galaxy list in case it ends up depleted
        galaxy_list = copy.deepcopy(banana_galaxies)
        galaxy_list = galaxy_list.values.tolist()
        galaxy_depleted = False
        slackmsg = ''
        matches = []
        slack_count = 0
        for x in range(0, len(observatories)):
            extra_matches = []
            # Check if all galaxies have been assigned, if so start assigning duplicates
            if len(galaxy_list) == 0:
                galaxy_list = copy.deepcopy(banana_galaxies)
                galaxy_list = galaxy_list.values.tolist()
                galaxy_depeleted = True
            telescope.lat = str(observatories['lat'][x]).strip()
            telescope.long = str(observatories['lon'][x]).strip()
            sun.compute(telescope)
            # if sun is up, observatory can be skipped
            if check_sun:
                if sun.alt > max_sun:
                    # print(str(observatories['Code'][x]) + " skipped, Sun is up")
                    continue
            for i in range(0, len(galaxy_list)):
                star = ephem.FixedBody()
                star._ra = ephem.degrees(str(galaxy_list[i][2]))
                star._dec = ephem.degrees(str(galaxy_list[i][3]))
                star.compute(telescope)

                # if the first object is more than 20 degrees below elevation, unlikely any objects will be higher than 45 degrees
                if check_minalt:
                    if star.alt < min_alt:
                        # print(str(observatories['Code'][x]) + " skipped " + str(star.alt) + " is less than -20 degrees")
                        break
                # assign galaxy to observer
                if star.alt > max_alt:
                    matches.append(
                        {'event_id': event, 'obs_ID': observatories['ID'][x], 'galaxy_id': galaxy_list[i][0]})
                    # print(galaxy_list[i])
                    listing = WEBSITE_URL+'/observe?key=' + str(
                        observatories['key'][x]) + '&event=' + str(event) + '&obs=' + str(
                        observatories['ID'][x]) + '&gal=' + str(galaxy_list[i][0]) + '&ra=' + str(
                        galaxy_list[i][2]) + '&dec=' + str(galaxy_list[i][3]) + '&fov=' + str(observatories['fov'][x])
                    print(listing)
                    if write_event:
                        event_log.writelines(listing)
                        event_log.write('\n')
                    #only writing the first 5 urls to slack
                    if send_slack:
                        if slack_count < 5:
                            slack_count += 1
                            slackmsg = slackmsg + listing + '\n'
                    #find extra galaxies within FOV
                    j = i+1
                    y = []
                    print(len(galaxy_list[j:]))
                    if galinfov:
                        for z in range(j,len(galaxy_list)):
                            extra = ephem.FixedBody()
                            extra._ra = ephem.degrees(str(galaxy_list[z][2]))
                            extra._dec = ephem.degrees(str(galaxy_list[z][3]))
                            extra.compute(telescope)
                            sep = float(ephem.separation(star,extra))*180/np.pi
                            if sep < 0.5/2:
                            #if sep < observatories['fov'][x]/2:
                                extra_matches.append({'event_id': event, 'obs_ID': observatories['ID'][x], 'galaxy_id': galaxy_list[z][0]})
                                print(z,sep,ephem.separation(star,extra))
                                y.append(z)
                    if len(y)>1:
                        print(y)
                        y.reverse()
                        for k in y:
                            del galaxy_list[k]
                            
                    # print(str(observatories['ID'][x]) + " " + observatories['name'][x].strip()[15:] + " at Lat:" +str(telescope.lat) + ",Lon:" + str(telescope.lon) + " gets galaxy " + str(galaxy_list[i][1]) + ' ra='+str(star.ra) + ' dec=' + str(star.dec) + ' alt='+str(star.alt))
                    del galaxy_list[i]
                    if plot_map:
                        plt.scatter(telescope.lon * 180 / np.pi, telescope.lat * 180 / np.pi, color='red',
                                    transform=ccrs.Geodetic())
                    break
            if len(extra_matches) > 0:
                extra_matches = pd.DataFrame(extra_matches)
                extra_matches.to_sql('matches_extra', sql_engine, if_exists='append', index=False)
        matches = pd.DataFrame(matches)
        matches.to_sql('matches', sql_engine, if_exists='append', index=False)
        event_log.close()
        if send_slack:
            if len(slackmsg) > 0:
                slack_client.chat_postMessage(channel=SLACK_CHANNEL, text=slackmsg)
                if galaxy_depleted:
                    text = "All" + str(len(banana_galaxies)) + " galaxies assigned"
                    query = "update events set assigned = " + str(len(banana_galaxies)) + ", possible = " + str(
                        len(banana_galaxies)) + " where ID = " + str(event)
                else:
                    text = str(len(banana_galaxies) - len(galaxy_list)) + " galaxies assigned out of " + str(
                        len(banana_galaxies))
                    query = "update events set assigned = " + str(
                        len(banana_galaxies) - len(galaxy_list)) + ", possible = " + str(
                        len(banana_galaxies)) + " where ID = " + str(event)
                    slack_client.chat_postMessage(channel=SLACK_CHANNEL, text=text)
                sql_engine.execute(query)
            else:
                slack_client.chat_postMessage(channel=SLACK_CHANNEL, text="No Galaxies Assigned")
        if plot_map:
            ax.add_feature(Nightshade(datetime.utcnow(), alpha=0.2))
            plt.title("Map of Observable Sites")
            plt.savefig("map.png")
            if send_slack:
                slack_client.files_upload(channels=SLACK_CHANNEL, file="map.png", title=params['GraceID'])
        filename = download_file(params['skymap_fits'], cache=True)
        skyplot([filename, '--annotate', '--geo', '--contour', '50', '90'])
        plt.savefig("hp.png")
        if send_slack:
            slack_client.files_upload(channels=SLACK_CHANNEL, file="hp.png", title=params['GraceID'])
        return
def plot_swath_grid(lon, lat, field, varname, levname, varunits, nrows, ncols,
                    cen_lon, date, nightshade, date_str, title_str):
    """
    ----------------------------------------------------------------------------
    This function plots a swath of footprint-level data
    FLASHFlux, SSF, or CRS
    ----------------------------------------------------------------------------
    :param lon: FOV longitude
    :param lat: FOV latitude
    :param field: variable
    :param varname: variable name
    :param levname: level name
    :param varunits: variable units
    :param nrows: number of rows
    :param ncols: number of columns
    :param cen_lon: central longitude
    :param cmap: colormap
    :param cmap_lims: colormap limits
    :param date: date info for nightshade
    :param nightshade: whether to use nighshade feature
    :param date_str: date string
    :param title_str: title string
    ----------------------------------------------------------------------------
    :return: plot of the data
    """
    import numpy as np
    import matplotlib.pyplot as plt
    import cartopy.crs as ccrs
    import cartopy.feature
    from mpl_toolkits.axes_grid1 import AxesGrid
    from cartopy.mpl.geoaxes import GeoAxes
    from cartopy.feature.nightshade import Nightshade

    # Map projection
    projection = ccrs.PlateCarree(central_longitude=cen_lon)

    # Axis class
    axes_class = (GeoAxes, dict(map_projection=projection))

    # Create figure
    fig = plt.figure(figsize=(11, 8))
    axgr = AxesGrid(fig,
                    111,
                    axes_class=axes_class,
                    nrows_ncols=(nrows, ncols),
                    axes_pad=(0.4, 0.4),
                    share_all=True,
                    cbar_location='right',
                    cbar_mode='single',
                    cbar_pad=+0.2,
                    cbar_size='3%',
                    label_mode=1)

    # Loop over axes
    for i, ax in enumerate(axgr):
        if i == 14:
            break
        ax.add_feature(cartopy.feature.LAND,
                       zorder=1,
                       facecolor='none',
                       edgecolor='darkgrey')
        ax.gridlines(color='grey', linestyle='--')
        ax.set_title(title_str + ' surface flux in band ' + str(i + 1) +
                     ' - all sky',
                     fontsize=8)
        ax.set_extent([-180, 180, -90, 90], projection)
        ax.text(0.5,
                -0.1,
                varname + ' - ' + levname + '\n' + varunits,
                va='bottom',
                ha='center',
                rotation='horizontal',
                rotation_mode='anchor',
                transform=ax.transAxes,
                fontsize=10)

        if nightshade == 1:
            ax.add_feature(Nightshade(date, alpha=0.1))

    # To use a different colorbar range each time, use a tuple of tuples
    # limits = ((0, 120), (0, 120), (0, 120), (0, 120), (0, 120), (0, 120), (0, 120),
    #           (0, 120), (0, 120), (0, 120), (0, 120), (0, 120), (0, 120), (0, 120))
    limits = (0, 70)
    for i in range((nrows * ncols)):
        if i == 14:
            break
        im = axgr[i].scatter(lon,
                             lat,
                             c=field[:, i],
                             s=1,
                             transform=ccrs.PlateCarree(),
                             vmin=limits[0],
                             vmax=limits[1],
                             cmap=lw_colormap)
        axgr.cbar_axes[i].colorbar(im)

    plt.tight_layout()
    plt.show()
    return
Exemplo n.º 30
0
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