def tester_s4(): """show contour from calpost with background in different projection plus annotated points""" from plotter import calpost_reader as reader import rasterio import cartopy.crs as ccrs import geopandas as gpd # source locations df = gpd.read_file(shpfile) df = df.to_crs('EPSG:3857') with open('../data/tseries_ch4_1min_conc_co_fl.dat') as f: dat = reader.Reader(f, slice(60 * 12, 60 * 12 + 10)) # background b = rasterio.open(bgfile) bext = [b.transform[2], b.transform[2] + b.transform[0] * b.width, b.transform[5] + b.transform[4] * b.height, b.transform[5]] plotter_options = { 'contour_options': {'alpha': .5}, 'extent': bext, 'projection': ccrs.epsg(3857), 'customize_once': [ lambda p: p.ax.imshow(b.read()[:3, :, :].transpose((1, 2, 0)), extent=bext, origin='upper'), lambda p: df.plot(ax=p.ax, column='kls', categorical=True, legend=True, zorder=10), lambda p: [p.ax.annotate(_.Site_Label, (_.geometry.x, _.geometry.y)) for _ in df.itertuples() if _.Site_Label in ('F1', 'op3_w1', 'S4')], lambda p: p.ax.gridlines(draw_labels=True), ]} x = dat['x'] * 1000 y = dat['y'] * 1000 p = Plotter(dat['v'], dat['ts'], x=x, y=y, plotter_options=plotter_options) p(outdir / 'test_s4.png')
def tester_bgm_b3(): """specify extent/projection and bg image""" from plotter import calpost_reader as reader import cartopy.crs as ccrs with open('../data/tseries_ch4_1min_conc_co_fl.dat') as f: dat = reader.Reader(f, slice(60 * 12, 60 * 12 + 10)) # background plotter_options = { 'contour_options': { 'alpha': .2 }, 'background_manager': BackgroundManager( bgfile=bgfile_lcc, projection=ccrs.epsg(3857), ), 'customize_once': lambda p: p.ax.gridlines(draw_labels=True), } x = dat['x'] * 1000 y = dat['y'] * 1000 p = Plotter(dat['v'], dat['ts'], x=x, y=y, plotter_options=plotter_options) p(outdir / 'test_bgm_b3.png')
def tester_bg3(): """specify extent, and use caropy.io.img_tiles.GootleTiles""" from plotter import calpost_reader as reader import cartopy.crs as ccrs import cartopy.io.img_tiles as cimgt with open('../data/tseries_ch4_1min_conc_co_fl.dat') as f: dat = reader.Reader(f, slice(60 * 12, 60 * 12 + 10)) # background bext = [-11344200.0, -11338900.0, 3724300.0, 3731100.0] plotter_options = { 'contour_options': { 'alpha': .2 }, 'extent': bext, 'projection': ccrs.epsg(3857), # GoogleMap, we may need license 'customize_once': lambda p: p.ax.add_image(cimgt.GoogleTiles(style='satellite'), 15) } x = dat['x'] * 1000 y = dat['y'] * 1000 p = Plotter(dat['v'], dat['ts'], x=x, y=y, plotter_options=plotter_options) p(outdir / 'test_bg3.png')
def tester_bg4(): """specify extent, and use NAIP images with cartopy.io.ogc_clients.WMSRasterSource""" from plotter import calpost_reader as reader import cartopy.crs as ccrs # import cartopy.io.ogc_clients as cogcc with open('../data/tseries_ch4_1min_conc_co_fl.dat') as f: dat = reader.Reader(f, slice(60 * 12, 60 * 12 + 10)) def my_add_naip(p): img = p.ax.add_wms( 'https://services.nationalmap.gov/arcgis/services/USGSNAIPImagery/ImageServer/WMSServer', layers='0') # TODO how can i save this...?, or should I save this? # background bext = [-11344200.0, -11338900.0, 3724300.0, 3731100.0] plotter_options = { 'contour_options': { 'alpha': .2 }, 'extent': bext, 'projection': ccrs.epsg(3857), # 'customize_once': lambda p: p.ax.add_wms( # 'https://services.nationalmap.gov/arcgis/services/USGSNAIPImagery/ImageServer/WMSServer', # layers='0' # ) 'customize_once': my_add_naip, } x = dat['x'] * 1000 y = dat['y'] * 1000 p = Plotter(dat['v'], dat['ts'], x=x, y=y, plotter_options=plotter_options) p(outdir / 'test_bg4.png')
def tester_bg1(): """load background tif file and use it""" from plotter import calpost_reader as reader import rasterio import cartopy.crs as ccrs with open('../data/tseries_ch4_1min_conc_co_fl.dat') as f: dat = reader.Reader(f, slice(60 * 12, 60 * 12 + 10)) # background b = rasterio.open(bgfile) bext = [ b.transform[2], b.transform[2] + b.transform[0] * b.width, b.transform[5] + b.transform[4] * b.height, b.transform[5] ] plotter_options = { 'contour_options': { 'alpha': .2 }, 'extent': bext, 'projection': ccrs.epsg(3857), 'customize_once': lambda p: p.ax.imshow(b.read()[:3, :, :].transpose((1, 2, 0)), extent=bext, origin='upper') } x = dat['x'] * 1000 y = dat['y'] * 1000 p = Plotter(dat['v'], dat['ts'], x=x, y=y, plotter_options=plotter_options) p(outdir / 'test_bg1.png')
def tester_bgm_b4b(): """background file, already processed to pseudo mercator, zoom in""" from plotter import calpost_reader as reader import cartopy.crs as ccrs with open('../data/tseries_ch4_1min_conc_co_fl.dat') as f: dat = reader.Reader(f, slice(60 * 12, 60 * 12 + 10)) bgm = BackgroundManager(bgfile=bgfile) ext = bgm.extent bgm.extent = [ 2 / 3 * ext[0] + 1 / 3 * ext[1], 1 / 3 * ext[0] + 2 / 3 * ext[1], 2 / 3 * ext[2] + 1 / 3 * ext[3], 1 / 3 * ext[2] + 2 / 3 * ext[3], ] # background plotter_options = { 'contour_options': { 'alpha': .2 }, 'background_manager': bgm, 'customize_once': lambda p: p.ax.gridlines(draw_labels=True), } x = dat['x'] * 1000 y = dat['y'] * 1000 p = Plotter(dat['v'], dat['ts'], x=x, y=y, plotter_options=plotter_options) p(outdir / 'test_bgm_b4b.png')
def tester_bgm_w2b(): """specify projection/extent, then wms""" from plotter import calpost_reader as reader import cartopy.crs as ccrs with open('../data/tseries_ch4_1min_conc_co_fl.dat') as f: dat = reader.Reader(f, slice(60 * 12, 60 * 12 + 10)) # background plotter_options = { 'contour_options': { 'alpha': .2 }, 'background_manager': BackgroundManager( projection=ccrs.epsg(3857), extent=[-11344200.0, -11338900.0, 3724300.0, 3731100.0]), 'customize_once': [ lambda p: p.ax.add_wms( 'https://services.nationalmap.gov/arcgis/services/USGSNAIPImagery/ImageServer/WMSServer', layers='0'), lambda p: p.ax.gridlines(draw_labels=True), ] } x = dat['x'] * 1000 y = dat['y'] * 1000 p = Plotter(dat['v'], dat['ts'], x=x, y=y, plotter_options=plotter_options) p(outdir / 'test_bgm_w2b.png')
def tester_md4(): from plotter import calpost_reader as reader with open('../data/tseries_ch4_1min_conc_co_fl.dat') as f: dat = reader.Reader(f, slice(60 * 12, 60 * 12 + 10)) titles = ['example', 'even more example....'] arrays = [dat['v'], dat['v']] x = dat['x'] * 1000 y = dat['y'] * 1000 plotter_options = { 'imshow_options': { 'origin': 'lower', # showing array as image require to specifie that grater y goes upward }, 'colorbar_options': None } plotter_options = [{**plotter_options, 'title': _} for _ in titles] figure_options = {'colorbar_options': {}} # make default font size smaller (default is 10) #mpl.rcParams.update({'font.size': 8}) p = Plotter(arrays, dat['ts'], x=x, y=y, plotter_options=plotter_options, figure_options=figure_options) p(outdir / 'test_md4.png', footnote=dat['ts'][0]) #, suptitle=dat['ts'][0])
def tester_s2(): """show contour from calpost plus annotated points""" from plotter import calpost_reader as reader import geopandas as gpd # source locations df = gpd.read_file(shpfile) df = df.to_crs( '+proj=lcc +lat_1=33 +lat_2=45 +lat_0=40 +lon_0=-97 +x_0=0 +y_0=0 +a=6370000 +b=6370000 +units=m +no_defs') with open('../data/tseries_ch4_1min_conc_co_fl.dat') as f: dat = reader.Reader(f, slice(60 * 12, 60 * 12 + 10)) plotter_options = { 'contour_options': {}, 'customize_once': [ lambda p: df.plot(ax=p.ax, column='kls', categorical=True, legend=True, zorder=10), lambda p: [p.ax.annotate(_.Site_Label, (_.geometry.x, _.geometry.y)) for _ in df.itertuples() if _.Site_Label in ('F1', 'op3_w1', 'S4')], lambda p: p.ax.gridlines(draw_labels=True), ] } x = dat['x'] * 1000 y = dat['y'] * 1000 p = Plotter(dat['v'], dat['ts'], x=x, y=y, plotter_options=plotter_options) p(outdir / 'test_s2.png')
def tester_bgm_w4(): """wms, specify projection/extent""" from plotter import calpost_reader as reader import cartopy.crs as ccrs with open('../data/tseries_ch4_1min_conc_co_fl.dat') as f: dat = reader.Reader(f, slice(60 * 12, 60 * 12 + 10)) # background plotter_options = { 'contour_options': { 'alpha': .2 }, 'background_manager': BackgroundManager(wms_options={ 'wms': 'https://services.nationalmap.gov/arcgis/services/USGSNAIPImagery/ImageServer/WMSServer', 'layers': '0' }, extent=[-465000.0, -460000.0, -902000.0, -907000.0]), #lcc, the data's projection 'customize_once': lambda p: p.ax.gridlines(draw_labels=True), } x = dat['x'] * 1000 y = dat['y'] * 1000 p = Plotter(dat['v'], dat['ts'], x=x, y=y, plotter_options=plotter_options) p(outdir / 'test_bgm_w4.png')
def tester_pc2(): """show contour from calpost""" from plotter import calpost_reader as reader with open('../data/tseries_ch4_1min_conc_co_fl.dat') as f: dat = reader.Reader(f, slice(60 * 12, 60 * 12 + 10)) plotter_options = {'contour_options': {}} x = dat['x'] * 1000 y = dat['y'] * 1000 p = Plotter(dat['v'], dat['ts'], x=x, y=y, plotter_options=plotter_options) p(outdir / 'test_pc2.png')
def tester_pr2b_v(quiet=False): """animate calpost raster""" from plotter import calpost_reader as reader import tempfile from pathlib import Path import shlex import subprocess with open('../data/tseries_ch4_1min_conc_co_fl.dat') as f: dat = reader.Reader(f, slice(60 * 12, 60 * 12 + 10)) plotter_options = { 'imshow_options': { 'origin': 'lower', # showing array as image require to specifie that grater y goes upward } } # since calpost tells x,y coordinates of each point, it is easier just pass those coords # dont forget that calpost has distance in km x = dat['x'] * 1000 y = dat['y'] * 1000 p = Plotter(dat['v'], dat['ts'], x=x, y=y, plotter_options=plotter_options) tstamps = dat['ts'] with tempfile.TemporaryDirectory() as wdir: workdir = Path(wdir) #print(workdir) # function to save one time frame def saveone(i): ts = tstamps[i] pname = workdir / f'{i:04}.png' #print(pname) footnote = str(ts) p(pname, tidx=i, footnote=footnote) n = len(tstamps) for i, ts in enumerate(tstamps): saveone(i) # make mpeg file if quiet: loglevel = '-loglevel error' else: loglevel = '' cmd = f'ffmpeg {loglevel} -i "{workdir / "%04d.png"}" -vframes 2880 -crf 3 -vcodec libx264 -pix_fmt yuv420p -f mp4 -y "{outdir / "test_pr2b.mp4"}"' #print(cmd) #print(shlex.split(cmd)) subprocess.run(shlex.split(cmd), check=True)
def tester_pr2b(): """show calpost raster""" from plotter import calpost_reader as reader with open('../data/tseries_ch4_1min_conc_co_fl.dat') as f: dat = reader.Reader(f, slice(60 * 12, 60 * 12 + 10)) plotter_options = { 'imshow_options': { 'origin': 'lower', # showing array as image require to specifie that grater y goes upward } } # since calpost tells x,y coordinates of each point, it is easier just pass those coords # dont forget that calpost has distance in km x = dat['x'] * 1000 y = dat['y'] * 1000 p = Plotter(dat['v'], dat['ts'], x=x, y=y, plotter_options=plotter_options) p(outdir / 'test_pr2b.png')
def tester_bgm_n0(): """no background or anything""" from plotter import calpost_reader as reader with open('../data/tseries_ch4_1min_conc_co_fl.dat') as f: dat = reader.Reader(f, slice(60 * 12, 60 * 12 + 10)) # background plotter_options = { 'contour_options': { 'alpha': .2 }, 'customize_once': lambda p: p.ax.gridlines(draw_labels=True), } x = dat['x'] * 1000 y = dat['y'] * 1000 p = Plotter(dat['v'], dat['ts'], x=x, y=y, plotter_options=plotter_options) p(outdir / 'test_bgm_n0.png')
def tester_md1(): from plotter import calpost_reader as reader with open('../data/tseries_ch4_1min_conc_co_fl.dat') as f: dat = reader.Reader(f, slice(60 * 12, 60 * 12 + 10)) titles = ['example', 'even more example....'] arrays = [dat['v'], dat['v']] x = dat['x'] * 1000 y = dat['y'] * 1000 plotter_options = { 'imshow_options': { 'origin': 'lower', # showing array as image require to specifie that grater y goes upward } } plotter_options = [{**plotter_options, 'title': _} for _ in titles] p = Plotter(arrays, dat['ts'], x=x, y=y, plotter_options=plotter_options) p(outdir / 'test_md1.png')
def tester_pc3(): """show contour from calpost in different projection""" from plotter import calpost_reader as reader import rasterio import cartopy.crs as ccrs with open('../data/tseries_ch4_1min_conc_co_fl.dat') as f: dat = reader.Reader(f, slice(60 * 12, 60 * 12 + 10)) # background b = rasterio.open(bgfile) bext = [b.transform[2], b.transform[2] + b.transform[0] * b.width, b.transform[5] + b.transform[4] * b.height, b.transform[5]] plotter_options = {'extent': bext, 'projection': ccrs.epsg(3857), 'contour_options': {}} x = dat['x'] * 1000 y = dat['y'] * 1000 p = Plotter(dat['v'], dat['ts'], x=x, y=y, plotter_options=plotter_options) p(outdir / 'test_pc3.png')
def tester_bgm_b1a(): """background file, dont have to tell its projection""" from plotter import calpost_reader as reader import cartopy.crs as ccrs with open('../data/tseries_ch4_1min_conc_co_fl.dat') as f: dat = reader.Reader(f, slice(60 * 12, 60 * 12 + 10)) # background plotter_options = { 'contour_options': { 'alpha': .2 }, 'background_manager': BackgroundManager(bgfile=bgfile), 'customize_once': lambda p: p.ax.gridlines(draw_labels=True), } x = dat['x'] * 1000 y = dat['y'] * 1000 p = Plotter(dat['v'], dat['ts'], x=x, y=y, plotter_options=plotter_options) p(outdir / 'test_bgm_b1a.png')
def tester_pr2a(): """show calpost raster""" from plotter import calpost_reader as reader with open('../data/tseries_ch4_1min_conc_co_fl.dat') as f: dat = reader.Reader(f, slice(60 * 12, 60 * 12 + 10)) g = dat['grid'] ext = [g['x0'], g['x0'] + g['nx'] * g['dx'], g['y0'], g['y0'] + g['ny'] * g['dy'], ] # distance in calpost is in km ext = [_ * 1000 for _ in ext] plotter_options = { 'imshow_options': { 'origin': 'lower', # showing array as image require to specifie that grater y goes upward } } p = Plotter(dat['v'], dat['ts'], extent=ext, plotter_options=plotter_options) p(outdir / 'test_pr2a.png')
def tester_bg2(): """load background tif file and use extent without showing it""" from plotter import calpost_reader as reader import cartopy.crs as ccrs with open('../data/tseries_ch4_1min_conc_co_fl.dat') as f: dat = reader.Reader(f, slice(60 * 12, 60 * 12 + 10)) # background bext = [-11344200.0, -11338900.0, 3724300.0, 3731100.0] plotter_options = { 'contour_options': { 'alpha': .2 }, 'extent': bext, 'projection': ccrs.epsg(3857), # 'customize_once': lambda p: p.ax.imshow(b.read()[:3, :, :].transpose((1, 2, 0)), # extent=bext, origin='upper') } x = dat['x'] * 1000 y = dat['y'] * 1000 p = Plotter(dat['v'], dat['ts'], x=x, y=y, plotter_options=plotter_options) p(outdir / 'test_bg2.png')
def tester_bgm_n4(): """specify only extent without bg image""" from plotter import calpost_reader as reader import cartopy.crs as ccrs with open('../data/tseries_ch4_1min_conc_co_fl.dat') as f: dat = reader.Reader(f, slice(60 * 12, 60 * 12 + 10)) # background plotter_options = { 'contour_options': { 'alpha': .2 }, 'background_manager': BackgroundManager(extent=[-465000.0, -460000.0, -902000.0, -907000.0 ]), # lcc extent larger than modeling 'customize_once': lambda p: p.ax.gridlines(draw_labels=True), } x = dat['x'] * 1000 y = dat['y'] * 1000 p = Plotter(dat['v'], dat['ts'], x=x, y=y, plotter_options=plotter_options) p(outdir / 'test_bgm_n4.png')
def tester_pc2_v(quiet=False): """animate contour from calpost""" from plotter import calpost_reader as reader import tempfile from pathlib import Path import shlex import subprocess with open('../data/tseries_ch4_1min_conc_co_fl.dat') as f: dat = reader.Reader(f, slice(60 * 12, 60 * 12 + 10)) plotter_options = {'contour_options': {}} x = dat['x'] * 1000 y = dat['y'] * 1000 p = Plotter(dat['v'], dat['ts'], x=x, y=y, plotter_options=plotter_options) tstamps = dat['ts'] with tempfile.TemporaryDirectory() as wdir: workdir = Path(wdir) # function to save one time frame def saveone(i): ts = tstamps[i] pname = workdir / f'{i:04}.png' footnote = str(ts) p(pname, tidx=i, footnote=footnote) n = len(tstamps) for i, ts in enumerate(tstamps): saveone(i) # make mpeg file if quiet: loglevel = '-loglevel error' else: loglevel = '' cmd = f'ffmpeg {loglevel} -i "{workdir / "%04d.png"}" -vframes 2880 -crf 3 -vcodec libx264 -pix_fmt yuv420p -f mp4 -y "{outdir / "test_pc2b.mp4"}"' subprocess.run(shlex.split(cmd))
df_shp = gpd.read_file(shpfile) df_shp = df_shp.to_crs('EPSG:3857') # title to use for each input titles = [ 'Regular Only', f'Regular +\nUnintended,\nContinous {site}', f'Regular +\nUnintended,\nPulsated {site}', ] # read the input, using calpost_reader.Reader() data = [] for fname in fnames: with open(ddir / fname) as f: # i am using only 16:00 to 16:10, for demo purpose dat = calpost_reader.Reader(f, tslice=slice(16 * 60, 16 * 60 + 10)) data.append(dat) # grab necessary info arrays = [dat['v'] for dat in data] tstamps = data[0]['ts'] grid = data[0]['grid'] # get horizontal extent # by matplotlib's convention, extent is expresses as [x0, x1, y0, y1] extent = [ grid['x0'], grid['x0'] + grid['nx'] * grid['dx'], grid['y0'], grid['y0'] + grid['ny'] * grid['dy'], ]
# aux inputs bgfile = '../resources/naip_toy_pmerc_5.tif' shpfile = '../resources/emitters.shp' # source locations df_shp = gpd.read_file(shpfile) df_shp = df_shp.to_crs('EPSG:3857') # title to use titles = ['Calpuff', 'Hysplit'] data = [None, None] # read calpuff with open(ddir / fnames[0]) as f: data[0] = calpost_reader.Reader(f) # read hysplit with open(ddir / fnames[1]) as f: x = np.arange(34) * 0.1 - 464.35 y = np.arange(47) * 0.1 - 906.65 data[1] = hysplit_reader.Reader(f, x=x, y=y) # grab necessary info assert data[1]['ts'][60] == data[0]['ts'][0] arrays = [ data[0]['v'][:23 * 60], data[1]['v'][60:], ] tstamps = data[0]['ts'][:23 * 60] grid = data[0]['grid']
sys.path.append('..') from plotter import plotter_solo as psolo, calpost_reader as reader import matplotlib as mpl from importlib import reload from plotter import plotter_util as pu reload(psolo) reload(pu) # save better resolution image mpl.rcParams['savefig.dpi'] = 300 fname = '../data/tseries_ch4_1min_conc_co_fl.dat' with open(fname) as f: dat = reader.Reader(f, slice(60 * 12, 60 * 12 + 1)) g = dat['grid'] ext = (g['x0'], g['x0'] + g['dx'] * g['nx'], g['y0'], g['y0'] + g['dy'] * g['ny']) ext = [_ * 1000 for _ in ext] print(ext) arr = dat['v'][:, ::-1, :] # https://ocefpaf.github.io/python4oceanographers/blog/2015/03/02/geotiff/ bga = pu.background_adder('../resources/gamma3_res2.tif') p = psolo.Plotter( arr, dat['ts'],
oname = 'tseries_ch4_1min_conc_co_fl_cnt.mp4' titles = ['raster', 'contour'] if not wdir.is_dir(): wdir.mkdir() else: for f in wdir.glob('*.png'): try: f.unlink() except OSError as e: print("Error: %s : %s" % (f, e.strerror)) # read the data with open(ddir / fname) as f: dat = reader.Reader(f) # grab necessary info arr = dat['v'] tstamps = dat['ts'] grid = dat['grid'] # get horizontal extent extent = [ grid['x0'], grid['x0'] + grid['nx'] * grid['dx'], grid['y0'], grid['y0'] + grid['ny'] * grid['dy'], ] extent = [_ * 1000 for _ in extent] print(extent)
7. / 12. * bext[2] + 5. / 12. * bext[3], 3. / 12. * bext[2] + 9. / 12. * bext[3], ] # source locations df = gpd.read_file(shpfile) df = df.to_crs('EPSG:3857') # read the data titles = ['Regular Only', f'Regular +\nUnintended,\nContinous {site}', f'Regular + \nUnintended,\nPulsated {site}'] data = [] for fname in fnames: print(ddir / fname, (ddir / fname).is_file()) with open(ddir / fname) as f: dat = reader.Reader(f, tslice=slice(16 * 60, 16 * 60 + 10)) data.append(dat) # grab necessary info arrays = [dat['v'] for dat in data] tstamps = data[0]['ts'] grid = data[0]['grid'] # get horizontal extent extent = [ grid['x0'], grid['x0'] + grid['nx'] * grid['dx'], grid['y0'], grid['y0'] + grid['ny'] * grid['dy'], ] # distance in calpost is in km extent = [_ * 1000 for _ in extent]
except OSError as e: print("Error: %s : %s" % (f, e.strerror)) # aux inputs bgfile = Path(plotterdir) / 'resources/naip_toy_pmerc_5.tif' shpfile = Path(plotterdir) / 'resources/emitters.shp' # source locations df_shp = gpd.read_file(shpfile) df_shp = df_shp.to_crs('EPSG:3857') # title to use title = 'Regular Sources' # read data dat = calpost_reader.Reader(ddir / fname) # grab necessary info arr = dat['v'] tstamps = dat['ts'] grid = dat['grid'] # get horizontal extent extent = [ grid['x0'], grid['x0'] + grid['nx'] * grid['dx'], grid['y0'], grid['y0'] + grid['ny'] * grid['dy'], ] # distance in calpost is in km
shpfile = Path(plotterdir) / 'resources/emitters.shp' # source locations df_shp = gpd.read_file(shpfile) df_shp = df_shp.to_crs('EPSG:3857') # title to use for each input titles = ['Regular Only', f'Regular +\nUnintended,\nContinous {site}', f'Regular + \nUnintended,\nPulsated {site}'] # read the data data = [] for fname in fnames: with open(ddir / fname) as f: dat = calpost_reader.Reader(f) data.append(dat) # grab necessary info arrays = [dat['v'] for dat in data] tstamps = data[0]['ts'] grid = data[0]['grid'] # get horizontal extent extent = [ grid['x0'], grid['x0'] + grid['nx'] * grid['dx'], grid['y0'], grid['y0'] + grid['ny'] * grid['dy'], ] # distance in calpost is in km extent = [_ * 1000 for _ in extent]
def tester_s5(quiet=True): """show contour from calpost with all the bells and whistles""" from plotter import calpost_reader as reader from plotter.plotter_util import LambertConformalTCEQ import rasterio import cartopy.crs as ccrs import geopandas as gpd import matplotlib.colors as colors from shapely.geometry import Polygon from adjustText import adjust_text import tempfile from pathlib import Path import shlex import subprocess # background (extent is used as plot's extent) b = rasterio.open(bgfile) bext = [b.transform[2], b.transform[2] + b.transform[0] * b.width, b.transform[5] + b.transform[4] * b.height, b.transform[5]] # source locations df = gpd.read_file(shpfile) df = df.to_crs('EPSG:3857') # read the data title = 'Flare' with open('../data/tseries_ch4_1min_conc_co_fl.dat') as f: dat = reader.Reader(f, slice(60 * 12, 60 * 12 + 10)) # grab necessary info arr = dat['v'] tstamps = dat['ts'] grid = dat['grid'] extent = [ grid['x0'], grid['x0'] + grid['nx'] * grid['dx'], grid['y0'], grid['y0'] + grid['ny'] * grid['dy'], ] # distance in calpost is in km extent = [_ * 1000 for _ in extent] x = dat['x'] * 1000 y = dat['y'] * 1000 # convert unit of array from g/m3 tp ppb # mwt g/mol # molar volume m3/mol arr = arr / 16.043 * 0.024465403697038 * 1e9 # Mrinali/Gary's surfer color scale cmap = colors.ListedColormap([ '#D6FAFE', '#02FEFF', '#C4FFC4', '#01FE02', '#FFEE02', '#FAB979', '#EF6601', '#FC0100', ]) cmap.set_under('#FFFFFF') # Define a normalization from values -> colors bndry = [1, 10, 50, 100, 200, 500, 1000, 2000] norm = colors.BoundaryNorm(bndry, len(bndry)) plotter_options = { 'extent': bext, 'projection': ccrs.epsg(3857), 'title': title, 'contour_options': { 'levels': bndry, 'cmap': cmap, 'norm': norm, 'alpha': .5, }, 'colorbar_options': { 'label': r'$CH_4$ (ppbV)', }, 'customize_once': [ # background lambda p: p.ax.imshow(b.read()[:3, :, :].transpose((1, 2, 0)), extent=bext, origin='upper'), # emission points lambda p: df.plot(ax=p.ax, column='kls', categorical=True, legend=False, zorder=10, markersize=2, # got red/blue/yellow from colorbrewer's Set1 cmap=colors.ListedColormap(['#e41a1c', '#377eb8', '#ffff33'])), # emission point annotations lambda p: adjust_text( # make list of annotation list( # this part creates annotation for each point p.ax.text(_.geometry.x, _.geometry.y, _.Site_Label, zorder=11, size=6) # goes across all points but filter by Site_Label for _ in df.itertuples() if _.Site_Label in ('F1', 'op3_w1', 'S4') ), # draw arrow from point to annotation arrowprops={'arrowstyle': '-'} ), # modeled box lambda p: p.ax.add_geometries( [Polygon([(extent[x],extent[y]) for x,y in ((0,2), (0,3), (1,3), (1,2), (0,2))])], crs=LambertConformalTCEQ(), facecolor='none', edgecolor='white', lw=.6, ), ]} # make a plot template p = Plotter(arr, dat['ts'], x=x, y=y, plotter_options=plotter_options) # make a plot p(outdir / 'test_s5.png') # make an animation with tempfile.TemporaryDirectory() as wdir: workdir = Path(wdir) # function to save one time frame def saveone(i): ts = tstamps[i] pname = workdir / f'{i:04}.png' footnote = str(ts) p(pname, tidx=i, footnote=footnote) n = len(tstamps) for i, ts in enumerate(tstamps): saveone(i) # make mpeg file if quiet: loglevel = '-loglevel error' else: loglevel = '' cmd = f'ffmpeg {loglevel} -i "{workdir / "%04d.png"}" -vframes 2880 -crf 3 -vcodec libx264 -pix_fmt yuv420p -f mp4 -y "{outdir / "test_pr2b.mp4"}"' subprocess.run(shlex.split(cmd))