def test_uv(): """ Test calculation of uv wind components """ speed = datatypes.speed([10], "KT") mydir = datatypes.direction([0], "DEG") u, v = meteorology.uv(speed, mydir) assert u.value("KT") == 0.0 assert v.value("KT") == -10.0 speed = datatypes.speed([10, 20, 15], "KT") mydir = datatypes.direction([90, 180, 135], "DEG") u, v = meteorology.uv(speed, mydir) assert u.value("KT")[0] == -10 assert v.value("KT")[1] == 20.0 assert abs(v.value("KT")[2] - 10.6) < 0.1
def test_uv(): """ Test calculation of uv wind components """ speed = datatypes.speed([10, ], 'KT') mydir = datatypes.direction([0, ], 'DEG') u, v = meteorology.uv(speed, mydir) assert u.value("KT") == 0. assert v.value("KT") == -10. speed = datatypes.speed([10, 20, 15], 'KT') mydir = datatypes.direction([90, 180, 135], 'DEG') u, v = meteorology.uv(speed, mydir) assert u.value("KT")[0] == -10 assert v.value("KT")[1] == 20. assert abs(v.value("KT")[2] - 10.6) < 0.1
def test_uv(self): """ Test calculation of uv wind components """ speed = datatypes.speed([10,], 'KT') mydir = datatypes.direction([0,], 'DEG') u,v = meteorology.uv(speed, mydir) self.assertEqual(u.value("KT"), 0.) self.assertEqual(v.value("KT"), -10.) speed = datatypes.speed([10,20,15], 'KT') mydir = datatypes.direction([90,180,135], 'DEG') u,v = meteorology.uv(speed, mydir) self.assertEqual(u.value("KT")[0], -10) self.assertEqual(v.value("KT")[1], 20.) self.assertAlmostEquals(v.value("KT")[2], 10.6, 1)
def plotter(fdict): """ Go """ import matplotlib matplotlib.use('agg') import matplotlib.pyplot as plt pgconn = psycopg2.connect(database='asos', host='iemdb', user='******') ctx = get_autoplot_context(fdict, get_description()) station = ctx['zstation'] network = ctx['network'] units = ctx['units'] nt = NetworkTable(network) df = read_sql(""" select date_trunc('hour', valid) as ts, avg(sknt) as sknt, max(drct) as drct from alldata WHERE station = %s and sknt is not null and drct is not null GROUP by ts """, pgconn, params=(station, ), parse_dates=('ts',), index_col=None) sknt = speed(df['sknt'].values, 'KT') drct = direction(df['drct'].values, 'DEG') df['u'], df['v'] = [x.value('MPS') for x in meteorology.uv(sknt, drct)] df['month'] = df['ts'].dt.month grp = df[['month', 'u', 'v', 'sknt']].groupby('month').mean() grp['u_%s' % (units,)] = speed(grp['u'].values, 'KT').value(units.upper()) grp['v_%s' % (units,)] = speed(grp['u'].values, 'KT').value(units.upper()) grp['sped_%s' % (units,)] = speed(grp['sknt'].values, 'KT').value(units.upper()) drct = meteorology.drct(speed(grp['u'].values, 'KT'), speed(grp['v'].values, 'KT')) grp['drct'] = drct.value('DEG') maxval = grp['sped_%s' % (units,)].max() (fig, ax) = plt.subplots(1, 1) ax.barh(grp.index.values, grp['sped_%s' % (units,)].values, align='center') ax.set_xlabel("Average Wind Speed [%s]" % (UNITS[units],)) ax.set_yticks(grp.index.values) ax.set_yticklabels(calendar.month_abbr[1:]) ax.grid(True) ax.set_xlim(0, maxval * 1.2) for mon, row in grp.iterrows(): ax.text(maxval * 1.1, mon, drct2text(row['drct']), ha='center', va='center', bbox=dict(color='white')) ax.text(row['sped_%s' % (units,)] * 0.98, mon, "%.1f" % (row['sped_%s' % (units,)],), ha='right', va='center', bbox=dict(color='white', boxstyle='square,pad=0.03',)) ax.set_ylim(12.5, 0.5) ax.set_title(("[%s] %s [%s-%s]\nMonthly Average Wind Speed and" " Vector Average Direction" ) % (station, nt.sts[station]['name'], df['ts'].min().year, df['ts'].max().year)) return fig, grp
def test_uv(self): """ Test calculation of uv wind components """ speed = datatypes.speed([ 10, ], 'KT') mydir = datatypes.direction([ 0, ], 'DEG') u, v = meteorology.uv(speed, mydir) self.assertEqual(u.value("KT"), 0.) self.assertEqual(v.value("KT"), -10.) speed = datatypes.speed([10, 20, 15], 'KT') mydir = datatypes.direction([90, 180, 135], 'DEG') u, v = meteorology.uv(speed, mydir) self.assertEqual(u.value("KT")[0], -10) self.assertEqual(v.value("KT")[1], 20.) self.assertAlmostEquals(v.value("KT")[2], 10.6, 1)
def plotter(fdict): """ Go """ import matplotlib matplotlib.use('agg') import matplotlib.pyplot as plt pgconn = get_dbconn('asos') ctx = get_autoplot_context(fdict, get_description()) station = ctx['zstation'] network = ctx['network'] units = ctx['units'] nt = NetworkTable(network) df = read_sql(""" select date_trunc('hour', valid at time zone 'UTC') as ts, avg(sknt) as sknt, max(drct) as drct from alldata WHERE station = %s and sknt is not null and drct is not null GROUP by ts """, pgconn, params=(station, ), index_col=None) sknt = speed(df['sknt'].values, 'KT') drct = direction(df['drct'].values, 'DEG') df['u'], df['v'] = [x.value('MPS') for x in meteorology.uv(sknt, drct)] df['month'] = df['ts'].dt.month grp = df[['month', 'u', 'v', 'sknt']].groupby('month').mean() grp['u_%s' % (units,)] = speed(grp['u'].values, 'KT').value(units.upper()) grp['v_%s' % (units,)] = speed(grp['u'].values, 'KT').value(units.upper()) grp['sped_%s' % (units,)] = speed(grp['sknt'].values, 'KT').value(units.upper()) drct = meteorology.drct(speed(grp['u'].values, 'KT'), speed(grp['v'].values, 'KT')) grp['drct'] = drct.value('DEG') maxval = grp['sped_%s' % (units,)].max() (fig, ax) = plt.subplots(1, 1) ax.barh(grp.index.values, grp['sped_%s' % (units,)].values, align='center') ax.set_xlabel("Average Wind Speed [%s]" % (UNITS[units],)) ax.set_yticks(grp.index.values) ax.set_yticklabels(calendar.month_abbr[1:]) ax.grid(True) ax.set_xlim(0, maxval * 1.2) for mon, row in grp.iterrows(): ax.text(maxval * 1.1, mon, drct2text(row['drct']), ha='center', va='center', bbox=dict(color='white')) ax.text(row['sped_%s' % (units,)] * 0.98, mon, "%.1f" % (row['sped_%s' % (units,)],), ha='right', va='center', bbox=dict(color='white', boxstyle='square,pad=0.03',)) ax.set_ylim(12.5, 0.5) ax.set_title(("[%s] %s [%s-%s]\nMonthly Average Wind Speed and" " Vector Average Direction" ) % (station, nt.sts[station]['name'], df['ts'].min().year, df['ts'].max().year)) return fig, grp
def do(valid, frame): """ Generate plot for a given timestamp """ cursor.execute( """select turbineid, power, ST_x(geom), ST_y(geom), yaw, windspeed from sampled_data s JOIN turbines t on (t.id = s.turbineid) WHERE valid = %s and power is not null and yaw is not null and windspeed is not null""", (valid, )) lons = [] lats = [] vals = [] u = [] v = [] for row in cursor: lons.append(row[2]) lats.append(row[3]) vals.append(row[1]) a, b = uv(speed(row[5], 'MPS'), direction(row[4], 'deg')) u.append(a.value('MPS')) v.append(b.value('MPS')) vals = np.array(vals) avgv = np.average(vals) vals2 = vals - avgv print valid, min(vals2), max(vals2) (fig, ax) = plt.subplots(1, 1) cmap = plt.cm.get_cmap('RdYlBu_r') cmap.set_under('white') cmap.set_over('black') clevs = np.arange(-300, 301, 50) norm = mpcolors.BoundaryNorm(clevs, cmap.N) ax.quiver(lons, lats, u, v, zorder=1) ax.scatter(lons, lats, c=vals2, vmin=-500, vmax=500, cmap=cmap, s=100, zorder=2) ax.set_title( "Pomeroy Farm Turbine Power [kW] Diff from Farm Avg (1min sampled dataset)\nValid: %s" % (valid.strftime("%d %b %Y %I:%M %p"))) make_colorbar(clevs, norm, cmap) fig.savefig('power_movie/frame%05i.png' % (frame, )) plt.close()
def grid_wind(df, domain): """ Grid winds based on u and v components @return uwnd, vwnd """ # compute components u = [] v = [] for _station, row in df.iterrows(): (_u, _v) = meteorology.uv(dt.speed(row["sknt"], "KT"), dt.direction(row["drct"], "DEG")) u.append(_u.value("MPS")) v.append(_v.value("MPS")) df["u"] = u df["v"] = v ugrid = generic_gridder(df, "u", domain) vgrid = generic_gridder(df, "v", domain) return ugrid, vgrid
def grid_wind(df, domain): """ Grid winds based on u and v components @return uwnd, vwnd """ # compute components u = [] v = [] for _station, row in df.iterrows(): (_u, _v) = meteorology.uv(dt.speed(row['sknt'], 'KT'), dt.direction(row['drct'], 'DEG')) u.append(_u.value("MPS")) v.append(_v.value("MPS")) df['u'] = u df['v'] = v ugrid = generic_gridder(df, 'u', domain) vgrid = generic_gridder(df, 'v', domain) return ugrid, vgrid
def do(valid, frame): """ Generate plot for a given timestamp """ cursor.execute("""select turbineid, power, ST_x(geom), ST_y(geom), yaw, windspeed from sampled_data s JOIN turbines t on (t.id = s.turbineid) WHERE valid = %s and power is not null and yaw is not null and windspeed is not null""", (valid,)) lons = [] lats = [] vals = [] u = [] v = [] for row in cursor: lons.append(row[2]) lats.append(row[3]) vals.append(row[1]) a,b = uv(speed(row[5], 'MPS'), direction(row[4], 'deg')) u.append( a.value('MPS') ) v.append( b.value('MPS') ) vals = np.array(vals) avgv = np.average(vals) vals2 = vals - avgv print valid, min(vals2), max(vals2) (fig, ax) = plt.subplots(1,1) cmap = plt.cm.get_cmap('RdYlBu_r') cmap.set_under('white') cmap.set_over('black') clevs = np.arange(-300,301,50) norm = mpcolors.BoundaryNorm(clevs, cmap.N) ax.quiver(lons, lats, u, v, zorder=1) ax.scatter(lons, lats, c=vals2, vmin=-500, vmax=500, cmap=cmap, s=100, zorder=2) ax.set_title("Pomeroy Farm Turbine Power [kW] Diff from Farm Avg (1min sampled dataset)\nValid: %s" % ( valid.strftime("%d %b %Y %I:%M %p"))) make_colorbar(clevs, norm, cmap) fig.savefig('power_movie/frame%05i.png' % (frame,)) plt.close()
def grid_wind(rs): """ Grid winds based on u and v components @param rs array of dicts @return uwnd, vwnd """ lats = [] lons = [] udata = [] vdata = [] for row in rs: if row['sknt'] is None or row['drct'] is None: continue # mps (u, v) = meteorology.uv(dt.speed(row['sknt'], 'KT'), dt.direction(row['drct'], 'DEG')) if v is not None: lats.append(nt.sts[row['station']]['lat']) lons.append(nt.sts[row['station']]['lon']) vdata.append(v.value("MPS")) udata.append(u.value("MPS")) if len(vdata) < 4: print "No wind data at all" return None xi, yi = np.meshgrid(iemre.XAXIS, iemre.YAXIS) nn = NearestNDInterpolator((lons, lats), np.array(udata)) ugrid = nn(xi, yi) nn = NearestNDInterpolator((lons, lats), np.array(vdata)) vgrid = nn(xi, yi) if ugrid is not None: ugt = ugrid vgt = vgrid return ugt, vgt else: return None, None
def grid_wind(rs): """ Grid winds based on u and v components @param rs array of dicts @return uwnd, vwnd """ lats = [] lons = [] udata = [] vdata = [] for row in rs: if row["sknt"] is None or row["drct"] is None: continue # mps (u, v) = meteorology.uv(dt.speed(row["sknt"], "KT"), dt.direction(row["drct"], "DEG")) if v is not None: lats.append(nt.sts[row["station"]]["lat"]) lons.append(nt.sts[row["station"]]["lon"]) vdata.append(v.value("MPS")) udata.append(u.value("MPS")) if len(vdata) < 4: print "No wind data at all" return None xi, yi = np.meshgrid(iemre.XAXIS, iemre.YAXIS) nn = NearestNDInterpolator((lons, lats), np.array(udata)) ugrid = nn(xi, yi) nn = NearestNDInterpolator((lons, lats), np.array(vdata)) vgrid = nn(xi, yi) if ugrid is not None: ugt = ugrid vgt = vgrid return ugt, vgt else: return None, None
def do(valid, yawsource): """ Generate plot for a given timestamp """ if yawsource not in ['yaw', 'yaw2', 'yaw3']: return yawdict = {'yaw': 'Orginal', 'yaw2': 'daryl corrected', 'yaw3': 'daryl v2'} if os.environ.get("SERVER_NAME", "") == 'iem.local': PGCONN = psycopg2.connect(database='mec', host='localhost', port='5555', user='******') else: PGCONN = psycopg2.connect(database='mec', host='iemdb', port='5432', user='******') cursor = PGCONN.cursor() cursor.execute( """select turbineid, power, ST_x(geom), ST_y(geom), """ + yawsource + """, windspeed, pitch from sampled_data s JOIN turbines t on (t.id = s.turbineid) WHERE valid = %s and power is not null and """ + yawsource + """ is not null and windspeed is not null and pitch is not null""", (valid, )) lons = [] lats = [] vals = [] u = [] v = [] ws = [] yaw = [] pitch = [] for row in cursor: lons.append(row[2]) lats.append(row[3]) vals.append(row[1]) ws.append(row[5]) yaw.append(row[4]) a, b = uv(speed(row[5], 'MPS'), direction(row[4], 'deg')) u.append(a.value('MPS')) v.append(b.value('MPS')) pitch.append(row[6]) pitch = np.array(pitch) vals = np.array(vals) avgv = np.average(vals) #vals2 = vals - avgv fig = plt.figure(figsize=(12.8, 7.2)) ax = fig.add_axes([0.14, 0.1, 0.52, 0.8]) cmap = plt.cm.get_cmap('jet') cmap.set_under('tan') cmap.set_over('black') clevs = np.arange(0, 1651, 150) norm = mpcolors.BoundaryNorm(clevs, cmap.N) ax.quiver(lons, lats, u, v, zorder=1) ax.scatter(lons, lats, c=vals, norm=norm, edgecolor='none', cmap=cmap, s=100, zorder=2) ax.get_yaxis().get_major_formatter().set_useOffset(False) ax.get_xaxis().get_major_formatter().set_useOffset(False) ax.set_title( "'I050' Farm Turbine Power [kW] (1min sampled dataset)\nValid: %s, yaw source: %s" % (valid.strftime("%d %b %Y %I:%M %p"), yawdict.get(yawsource, yawsource))) make_colorbar(clevs, norm, cmap) ax.text(0.05, 0.05, "Turbine Power: $\mu$= %.1f $\sigma$= %.1f kW" % (avgv, np.std(vals)), transform=ax.transAxes) ax.text(0.05, 0.01, "Wind $\mu$= %.1f $\sigma$= %.1f $ms^{-1}$" % (np.average(ws), np.std(ws)), transform=ax.transAxes) ax.set_xlabel("Longitude $^\circ$E") ax.set_ylabel("Latitude $^\circ$N") ax.set_xlim(-94.832, -94.673) ax.set_ylim(42.545, 42.671) # Next plot ax2 = fig.add_axes([0.7, 0.80, 0.28, 0.18]) ax2.scatter(ws, vals, edgecolor='k', c='k') ax2.text(0.5, -0.25, "Wind Speed $ms^{-1}$", transform=ax2.transAxes, ha='center') ax2.set_xlim(0, 20) #ax2.set_ylabel("Power kW") ax2.grid(True) # Next plot ax3 = fig.add_axes([0.7, 0.57, 0.28, 0.18], sharey=ax2) ax3.scatter(yaw, vals, edgecolor='k', c='k') ax3.text(0.5, -0.25, "Yaw", transform=ax3.transAxes, ha='center') #ax3.set_ylabel("Power kW") ax3.set_xlim(0, 360) ax3.set_xticks(np.arange(0, 361, 45)) ax3.set_xticklabels(['N', 'NE', 'E', 'SE', 'S', 'SW', 'W', 'NW', 'N']) ax3.grid(True) # Next plot ax4 = fig.add_axes([0.7, 0.32, 0.28, 0.18], sharey=ax2) ax4.scatter(pitch, vals, edgecolor='k', c='k') ax4.text(0.5, -0.25, "Pitch $^\circ$", transform=ax4.transAxes, ha='center') ax4.set_ylim(-10, 1600) ax4.grid(True) # Next plot ax5 = fig.add_axes([0.7, 0.07, 0.28, 0.18], sharex=ax4) ax5.scatter(pitch, ws, edgecolor='k', c='k') ax5.text(0.5, -0.25, "Pitch $^\circ$", transform=ax5.transAxes, ha='center') ax5.grid(True) ax5.set_ylim(bottom=-10) #maxpitch = max(np.where(pitch > 20, 0, pitch)) #ax5.set_xlim(np.ma.minimum(pitch)-0.5, maxpitch+0.5) ax5.set_xlim(-3, 20.1) ax5.set_ylim(0, 20) ax5.text(-0.1, 0.5, "Wind Speed $ms^{-1}$", transform=ax5.transAxes, ha='center', va='center', rotation=90) plt.savefig(sys.stdout)
def simple(grids, valid, iarchive): """Simple gridder (stub for now)""" if iarchive: pgconn = psycopg2.connect(database='asos', host='iemdb', user='******') df = read_sql(""" SELECT ST_x(geom) as lon, ST_y(geom) as lat, tmpf, dwpf, sknt, drct, vsby from alldata c JOIN stations t on (c.station = t.id) WHERE c.valid >= %s and c.valid < %s and t.network in ('IA_ASOS', 'AWOS', 'MN_ASOS', 'WI_ASOS', 'IL_ASOS', 'MO_ASOS', 'NE_ASOS', 'KS_ASOS', 'SD_ASOS') and sknt is not null and drct is not null and tmpf is not null and dwpf is not null and vsby is not null """, pgconn, params=((valid - datetime.timedelta(minutes=30)), (valid + datetime.timedelta(minutes=30))), index_col=None) else: pgconn = psycopg2.connect(database='iem', host='iemdb', user='******') df = read_sql(""" SELECT ST_x(geom) as lon, ST_y(geom) as lat, tmpf, dwpf, sknt, drct, vsby from current c JOIN stations t on (c.iemid = t.iemid) WHERE c.valid > now() - '1 hour'::interval and t.network in ('IA_ASOS', 'AWOS', 'MN_ASOS', 'WI_ASOS', 'IL_ASOS', 'MO_ASOS', 'NE_ASOS', 'KS_ASOS', 'SD_ASOS') and sknt is not null and drct is not null and tmpf is not null and dwpf is not null and vsby is not null """, pgconn, index_col=None) if len(df.index) < 5: print(("i5gridder abort len(data): %s for %s iarchive: %s" % (len(df.index), valid, iarchive))) sys.exit() nn = NearestNDInterpolator((df['lon'].values, df['lat'].values), temperature(df['tmpf'].values, 'F').value('C')) grids['tmpc'] = nn(XI, YI) nn = NearestNDInterpolator((df['lon'].values, df['lat'].values), temperature(df['dwpf'].values, 'F').value('C')) grids['dwpc'] = nn(XI, YI) nn = NearestNDInterpolator((df['lon'].values, df['lat'].values), speed(df['sknt'].values, 'KT').value('MPS')) grids['smps'] = nn(XI, YI) u, v = meteorology.uv(speed(df['sknt'].values, 'KT'), direction(df['drct'].values, 'DEG')) nn = NearestNDInterpolator((df['lon'].values, df['lat'].values), u.value('MPS')) ugrid = nn(XI, YI) nn = NearestNDInterpolator((df['lon'].values, df['lat'].values), v.value('MPS')) vgrid = nn(XI, YI) drct = meteorology.drct(speed(ugrid.ravel(), 'MPS'), speed(vgrid.ravel(), 'MPS') ).value('DEG').astype('i') grids['drct'] = np.reshape(drct, (len(YAXIS), len(XAXIS))) nn = NearestNDInterpolator((df['lon'].values, df['lat'].values), distance(df['vsby'].values, 'MI').value('KM')) grids['vsby'] = nn(XI, YI)
def do(valid, yawsource): """ Generate plot for a given timestamp """ pgconn = get_dbconn('scada') cursor = pgconn.cursor() cursor.execute("""select turbine_id, power, lon, lat, yawangle, windspeed, alpha1 from data s JOIN turbines t on (t.id = s.turbine_id) WHERE valid = %s and power is not null and yawangle is not null and windspeed is not null and alpha1 is not null""", (valid,)) lons = [] lats = [] vals = [] u = [] v = [] ws = [] yaw = [] pitch = [] for row in cursor: lons.append(row[2]) lats.append(row[3]) vals.append(row[1]) ws.append(row[5]) yaw.append(row[4]) a, b = uv(speed(row[5], 'MPS'), direction(row[4], 'deg')) u.append(a.value('MPS')) v.append(b.value('MPS')) pitch.append(row[6]) pitch = np.array(pitch) vals = np.array(vals) avgv = np.average(vals) # vals2 = vals - avgv fig = plt.figure(figsize=(12.8, 7.2)) ax = fig.add_axes([0.14, 0.1, 0.52, 0.8]) cmap = plt.cm.get_cmap('jet') cmap.set_under('tan') cmap.set_over('black') # cmap = plt.cm.get_cmap('seismic') # clevs = np.arange(-250, 251, 50) clevs = np.arange(0, 1501, 150) norm = mpcolors.BoundaryNorm(clevs, cmap.N) ax.quiver(lons, lats, u, v, zorder=1) ax.scatter(lons, lats, c=vals, norm=norm, edgecolor='none', cmap=cmap, s=100, zorder=2) ax.get_yaxis().get_major_formatter().set_useOffset(False) ax.get_xaxis().get_major_formatter().set_useOffset(False) ax.xaxis.set_major_formatter(plt.NullFormatter()) ax.yaxis.set_major_formatter(plt.NullFormatter()) ax.set_title(("Turbine Power [kW]\n" "Valid: %s" ) % (valid.strftime("%d %b %Y %I:%M %p"))) make_colorbar(clevs, norm, cmap) ax.text(0.05, 0.05, "Turbine Power: $\mu$= %.1f $\sigma$= %.1f kW" % ( avgv, np.std(vals)), transform=ax.transAxes) ax.text(0.05, 0.01, "Wind $\mu$= %.1f $\sigma$= %.1f $ms^{-1}$" % ( np.average(ws), np.std(ws)), transform=ax.transAxes) ax.set_xlabel("Longitude $^\circ$E") ax.set_ylabel("Latitude $^\circ$N") ax.set_xlim(-93.475, -93.328) ax.set_ylim(42.20, 42.31) # Next plot ax2 = fig.add_axes([0.7, 0.80, 0.28, 0.18]) ax2.scatter(ws, vals, edgecolor='k', c='k') ax2.text(0.5, -0.25, "Wind Speed $ms^{-1}$", transform=ax2.transAxes, ha='center') ax2.set_xlim(0, 20) # ax2.set_ylabel("Power kW") ax2.grid(True) # Next plot ax3 = fig.add_axes([0.7, 0.57, 0.28, 0.18], sharey=ax2) ax3.scatter(yaw, vals, edgecolor='k', c='k') ax3.text(0.5, -0.25, "Yaw", transform=ax3.transAxes, ha='center') # ax3.set_ylabel("Power kW") ax3.set_xlim(0, 360) ax3.set_xticks(np.arange(0, 361, 45)) ax3.set_xticklabels(['N', 'NE', 'E', 'SE', 'S', 'SW', 'W', 'NW', 'N']) ax3.grid(True) # Next plot ax4 = fig.add_axes([0.7, 0.32, 0.28, 0.18], sharey=ax2) ax4.scatter(pitch, vals, edgecolor='k', c='k') ax4.text(0.5, -0.25, "Pitch $^\circ$", transform=ax4.transAxes, ha='center') ax4.set_ylim(-10, 1600) ax4.grid(True) # Next plot ax5 = fig.add_axes([0.7, 0.07, 0.28, 0.18], sharex=ax4) ax5.scatter(pitch, ws, edgecolor='k', c='k') ax5.text(0.5, -0.25, "Pitch $^\circ$", transform=ax5.transAxes, ha='center') ax5.grid(True) ax5.set_ylim(bottom=-10) # maxpitch = max(np.where(pitch > 20, 0, pitch)) # ax5.set_xlim(np.ma.minimum(pitch)-0.5, maxpitch+0.5) ax5.set_xlim(-3, 20.1) ax5.set_ylim(0, 20) ax5.text(-0.1, 0.5, "Wind Speed $ms^{-1}$", transform=ax5.transAxes, ha='center', va='center', rotation=90) plt.savefig(getattr(sys.stdout, 'buffer', sys.stdout))
def do(valid, yawsource): """ Generate plot for a given timestamp """ PGCONN = psycopg2.connect(database='scada', host='iemdb', user='******') cursor = PGCONN.cursor() cursor.execute("""select turbine_id, power, lon, lat, yawangle, windspeed, alpha1 from data s JOIN turbines t on (t.id = s.turbine_id) WHERE valid = %s and power is not null and yawangle is not null and windspeed is not null and alpha1 is not null""", (valid,)) lons = [] lats = [] vals = [] u = [] v = [] ws = [] yaw = [] pitch = [] for row in cursor: lons.append(row[2]) lats.append(row[3]) vals.append(row[1]) ws.append(row[5]) yaw.append(row[4]) a, b = uv(speed(row[5], 'MPS'), direction(row[4], 'deg')) u.append(a.value('MPS')) v.append(b.value('MPS')) pitch.append(row[6]) pitch = np.array(pitch) vals = np.array(vals) avgv = np.average(vals) vals2 = vals - avgv fig = plt.figure(figsize=(12.8, 7.2)) ax = fig.add_axes([0.14, 0.1, 0.52, 0.8]) cmap = plt.cm.get_cmap('jet') cmap.set_under('tan') cmap.set_over('black') # cmap = plt.cm.get_cmap('seismic') # clevs = np.arange(-250, 251, 50) clevs = np.arange(0, 1501, 150) norm = mpcolors.BoundaryNorm(clevs, cmap.N) ax.quiver(lons, lats, u, v, zorder=1) ax.scatter(lons, lats, c=vals, norm=norm, edgecolor='none', cmap=cmap, s=100, zorder=2) ax.get_yaxis().get_major_formatter().set_useOffset(False) ax.get_xaxis().get_major_formatter().set_useOffset(False) ax.xaxis.set_major_formatter(plt.NullFormatter()) ax.yaxis.set_major_formatter(plt.NullFormatter()) ax.set_title(("Turbine Power [kW]\n" "Valid: %s" ) % (valid.strftime("%d %b %Y %I:%M %p"))) make_colorbar(clevs, norm, cmap) ax.text(0.05, 0.05, "Turbine Power: $\mu$= %.1f $\sigma$= %.1f kW" % ( avgv, np.std(vals)), transform=ax.transAxes) ax.text(0.05, 0.01, "Wind $\mu$= %.1f $\sigma$= %.1f $ms^{-1}$" % ( np.average(ws), np.std(ws)), transform=ax.transAxes) ax.set_xlabel("Longitude $^\circ$E") ax.set_ylabel("Latitude $^\circ$N") ax.set_xlim(-93.475, -93.328) ax.set_ylim(42.20, 42.31) # Next plot ax2 = fig.add_axes([0.7, 0.80, 0.28, 0.18]) ax2.scatter(ws, vals, edgecolor='k', c='k') ax2.text(0.5, -0.25, "Wind Speed $ms^{-1}$", transform=ax2.transAxes, ha='center') ax2.set_xlim(0, 20) # ax2.set_ylabel("Power kW") ax2.grid(True) # Next plot ax3 = fig.add_axes([0.7, 0.57, 0.28, 0.18], sharey=ax2) ax3.scatter(yaw, vals, edgecolor='k', c='k') ax3.text(0.5, -0.25, "Yaw", transform=ax3.transAxes, ha='center') # ax3.set_ylabel("Power kW") ax3.set_xlim(0, 360) ax3.set_xticks(np.arange(0, 361, 45)) ax3.set_xticklabels(['N', 'NE', 'E', 'SE', 'S', 'SW', 'W', 'NW', 'N']) ax3.grid(True) # Next plot ax4 = fig.add_axes([0.7, 0.32, 0.28, 0.18], sharey=ax2) ax4.scatter(pitch, vals, edgecolor='k', c='k') ax4.text(0.5, -0.25, "Pitch $^\circ$", transform=ax4.transAxes, ha='center') ax4.set_ylim(-10, 1600) ax4.grid(True) # Next plot ax5 = fig.add_axes([0.7, 0.07, 0.28, 0.18], sharex=ax4) ax5.scatter(pitch, ws, edgecolor='k', c='k') ax5.text(0.5, -0.25, "Pitch $^\circ$", transform=ax5.transAxes, ha='center') ax5.grid(True) ax5.set_ylim(bottom=-10) # maxpitch = max(np.where(pitch > 20, 0, pitch)) # ax5.set_xlim(np.ma.minimum(pitch)-0.5, maxpitch+0.5) ax5.set_xlim(-3, 20.1) ax5.set_ylim(0, 20) ax5.text(-0.1, 0.5, "Wind Speed $ms^{-1}$", transform=ax5.transAxes, ha='center', va='center', rotation=90) plt.savefig(sys.stdout)
def do(ts): """Process this date timestamp""" asos = psycopg2.connect(database='asos', host='iemdb', user='******') cursor = asos.cursor() iemaccess = psycopg2.connect(database='iem', host='iemdb') icursor = iemaccess.cursor() cursor.execute(""" select station, network, iemid, drct, sknt, valid at time zone tzname, tmpf, dwpf from alldata d JOIN stations t on (t.id = d.station) where (network ~* 'ASOS' or network = 'AWOS') and valid between %s and %s and t.tzname is not null ORDER by valid ASC """, (ts - datetime.timedelta(days=2), ts + datetime.timedelta(days=2))) wdata = dict() rhdata = dict() for row in cursor: if row[5].strftime("%m%d") != ts.strftime("%m%d"): continue station = "%s|%s|%s" % (row[0], row[1], row[2]) if row[6] is not None and row[7] is not None: tmpf = temperature(row[6], 'F') dwpf = temperature(row[7], 'F') rh = meteorology.relh(tmpf, dwpf) if station not in rhdata: rhdata[station] = dict(valid=[], rh=[]) rhdata[station]['valid'].append(row[5]) rhdata[station]['rh'].append(rh.value('%')) if row[4] is not None and row[3] is not None: sknt = speed(row[4], 'KT') drct = direction(row[3], 'DEG') (u, v) = meteorology.uv(sknt, drct) if station not in wdata: wdata[station] = {'valid': [], 'sknt': [], 'u': [], 'v': []} wdata[station]['valid'].append(row[5]) wdata[station]['sknt'].append(row[4]) wdata[station]['u'].append(u.value('KT')) wdata[station]['v'].append(v.value('KT')) table = "summary_%s" % (ts.year,) for stid in rhdata: # Not enough data if len(rhdata[stid]['valid']) < 6: continue station, network, iemid = stid.split("|") now = datetime.datetime(ts.year, ts.month, ts.day) runningrh = 0 runningtime = 0 for i, valid in enumerate(rhdata[stid]['valid']): delta = (valid - now).seconds runningtime += delta runningrh += (delta * rhdata[stid]['rh'][i]) now = valid if runningtime == 0: print(("compute_daily %s has time domain %s %s" ) % (stid, rhdata[stid]['valid'][0], rhdata[stid]['valid'][-1])) continue avg_rh = clean_rh(runningrh / runningtime) min_rh = clean_rh(min(rhdata[stid]['rh'])) max_rh = clean_rh(max(rhdata[stid]['rh'])) def do_update(): icursor.execute("""UPDATE """ + table + """ SET avg_rh = %s, min_rh = %s, max_rh = %s WHERE iemid = %s and day = %s""", (avg_rh, min_rh, max_rh, iemid, ts)) do_update() if icursor.rowcount == 0: print(('compute_daily Adding %s for %s %s %s' ) % (table, station, network, ts)) icursor.execute("""INSERT into """ + table + """ (iemid, day) values (%s, %s)""", (iemid, ts)) do_update() for stid in wdata: # Not enough data if len(wdata[stid]['valid']) < 6: continue station, network, iemid = stid.split("|") now = datetime.datetime(ts.year, ts.month, ts.day) runningsknt = 0 runningtime = 0 runningu = 0 runningv = 0 for i, valid in enumerate(wdata[stid]['valid']): delta = (valid - now).seconds runningtime += delta runningsknt += (delta * wdata[stid]['sknt'][i]) runningu += (delta * wdata[stid]['u'][i]) runningv += (delta * wdata[stid]['v'][i]) now = valid if runningtime == 0: print(("compute_daily %s has time domain %s %s" ) % (stid, wdata[stid]['valid'][0], wdata[stid]['valid'][-1])) continue sknt = runningsknt / runningtime u = speed(runningu / runningtime, 'KT') v = speed(runningv / runningtime, 'KT') drct = meteorology.drct(u, v).value("DEG") def do_update(): icursor.execute("""UPDATE """ + table + """ SET avg_sknt = %s, vector_avg_drct = %s WHERE iemid = %s and day = %s""", (sknt, drct, iemid, ts)) do_update() if icursor.rowcount == 0: print(('compute_daily Adding %s for %s %s %s' ) % (table, station, network, ts)) icursor.execute("""INSERT into """ + table + """ (iemid, day) values (%s, %s)""", (iemid, ts)) do_update() icursor.close() iemaccess.commit() iemaccess.close()
def do(valid, yawsource): """ Generate plot for a given timestamp """ if yawsource not in ['yaw', 'yaw2', 'yaw3']: return yawdict = {'yaw': 'Orginal', 'yaw2': 'daryl corrected', 'yaw3': 'daryl v2'} if os.environ.get("SERVER_NAME", "") == 'iem.local': PGCONN = psycopg2.connect(database='mec', host='localhost', port='5555', user='******') else: PGCONN = psycopg2.connect(database='mec', host='iemdb', port='5432', user='******') cursor = PGCONN.cursor() cursor.execute("""select turbineid, power, ST_x(geom), ST_y(geom), """+yawsource+""", windspeed, pitch from sampled_data s JOIN turbines t on (t.id = s.turbineid) WHERE valid = %s and power is not null and """+yawsource+""" is not null and windspeed is not null and pitch is not null""", (valid,)) lons = [] lats = [] vals = [] u = [] v = [] ws = [] yaw = [] pitch = [] for row in cursor: lons.append(row[2]) lats.append(row[3]) vals.append(row[1]) ws.append( row[5] ) yaw.append( row[4]) a,b = uv(speed(row[5], 'MPS'), direction(row[4], 'deg')) u.append( a.value('MPS') ) v.append( b.value('MPS') ) pitch.append(row[6]) pitch = np.array(pitch) vals = np.array(vals) avgv = np.average(vals) #vals2 = vals - avgv fig = plt.figure(figsize=(12.8,7.2)) ax = fig.add_axes([0.14, 0.1, 0.52, 0.8]) cmap = plt.cm.get_cmap('jet') cmap.set_under('tan') cmap.set_over('black') clevs = np.arange(0,1651,150) norm = mpcolors.BoundaryNorm(clevs, cmap.N) ax.quiver(lons, lats, u, v, zorder=1) ax.scatter(lons, lats, c=vals, norm=norm, edgecolor='none', cmap=cmap, s=100, zorder=2) ax.get_yaxis().get_major_formatter().set_useOffset(False) ax.get_xaxis().get_major_formatter().set_useOffset(False) ax.set_title("'I050' Farm Turbine Power [kW] (1min sampled dataset)\nValid: %s, yaw source: %s" % ( valid.strftime("%d %b %Y %I:%M %p"), yawdict.get(yawsource, yawsource))) make_colorbar(clevs, norm, cmap) ax.text(0.05, 0.05, "Turbine Power: $\mu$= %.1f $\sigma$= %.1f kW" % ( avgv, np.std(vals)), transform=ax.transAxes) ax.text(0.05, 0.01, "Wind $\mu$= %.1f $\sigma$= %.1f $ms^{-1}$" % ( np.average(ws), np.std(ws)), transform=ax.transAxes) ax.set_xlabel("Longitude $^\circ$E") ax.set_ylabel("Latitude $^\circ$N") ax.set_xlim(-94.832, -94.673) ax.set_ylim(42.545, 42.671) # Next plot ax2 = fig.add_axes([0.7, 0.80, 0.28, 0.18]) ax2.scatter(ws, vals, edgecolor='k', c='k') ax2.text(0.5, -0.25, "Wind Speed $ms^{-1}$", transform=ax2.transAxes, ha='center') ax2.set_xlim(0,20) #ax2.set_ylabel("Power kW") ax2.grid(True) # Next plot ax3 = fig.add_axes([0.7, 0.57, 0.28, 0.18], sharey=ax2) ax3.scatter(yaw, vals, edgecolor='k', c='k') ax3.text(0.5, -0.25, "Yaw", transform=ax3.transAxes, ha='center') #ax3.set_ylabel("Power kW") ax3.set_xlim(0,360) ax3.set_xticks(np.arange(0,361,45)) ax3.set_xticklabels(['N', 'NE', 'E', 'SE', 'S', 'SW', 'W', 'NW', 'N']) ax3.grid(True) # Next plot ax4 = fig.add_axes([0.7, 0.32, 0.28, 0.18], sharey=ax2) ax4.scatter(pitch, vals, edgecolor='k', c='k') ax4.text(0.5, -0.25, "Pitch $^\circ$", transform=ax4.transAxes, ha='center') ax4.set_ylim(-10,1600) ax4.grid(True) # Next plot ax5 = fig.add_axes([0.7, 0.07, 0.28, 0.18], sharex=ax4) ax5.scatter(pitch, ws, edgecolor='k', c='k') ax5.text(0.5, -0.25, "Pitch $^\circ$", transform=ax5.transAxes, ha='center') ax5.grid(True) ax5.set_ylim(bottom=-10) #maxpitch = max(np.where(pitch > 20, 0, pitch)) #ax5.set_xlim(np.ma.minimum(pitch)-0.5, maxpitch+0.5) ax5.set_xlim(-3, 20.1) ax5.set_ylim(0,20) ax5.text(-0.1, 0.5, "Wind Speed $ms^{-1}$", transform=ax5.transAxes, ha='center', va='center', rotation=90) plt.savefig( sys.stdout )
def do(valid, yawsource): """ Generate plot for a given timestamp """ if yawsource not in ["yaw", "yaw2", "yaw3"]: return yawdict = {"yaw": "Orginal", "yaw2": "daryl corrected", "yaw3": "daryl v2"} pgconn = get_dbconn("mec") cursor = pgconn.cursor() cursor.execute( """select turbineid, power, ST_x(geom), ST_y(geom), """ + yawsource + """, windspeed, pitch from sampled_data s JOIN turbines t on (t.id = s.turbineid) WHERE valid = %s and power is not null and """ + yawsource + """ is not null and windspeed is not null and pitch is not null""", (valid, ), ) lons = [] lats = [] vals = [] u = [] v = [] ws = [] yaw = [] pitch = [] for row in cursor: lons.append(row[2]) lats.append(row[3]) vals.append(row[1]) ws.append(row[5]) yaw.append(row[4]) a, b = uv(speed(row[5], "MPS"), direction(row[4], "deg")) u.append(a.value("MPS")) v.append(b.value("MPS")) pitch.append(row[6]) pitch = np.array(pitch) vals = np.array(vals) avgv = np.average(vals) # vals2 = vals - avgv fig = plt.figure(figsize=(12.8, 7.2)) ax = fig.add_axes([0.14, 0.1, 0.52, 0.8]) cmap = plt.cm.get_cmap("jet") cmap.set_under("tan") cmap.set_over("black") clevs = np.arange(0, 1651, 150) norm = mpcolors.BoundaryNorm(clevs, cmap.N) ax.quiver(lons, lats, u, v, zorder=1) ax.scatter( lons, lats, c=vals, norm=norm, edgecolor="none", cmap=cmap, s=100, zorder=2, ) ax.get_yaxis().get_major_formatter().set_useOffset(False) ax.get_xaxis().get_major_formatter().set_useOffset(False) ax.set_title(("Farm Turbine Power [kW] (1min sampled dataset)\n" "Valid: %s, yaw source: %s") % ( valid.strftime("%d %b %Y %I:%M %p"), yawdict.get(yawsource, yawsource), )) make_colorbar(clevs, norm, cmap) ax.text( 0.05, 0.05, "Turbine Power: $\mu$= %.1f $\sigma$= %.1f kW" % (avgv, np.std(vals)), transform=ax.transAxes, ) ax.text( 0.05, 0.01, "Wind $\mu$= %.1f $\sigma$= %.1f $ms^{-1}$" % (np.average(ws), np.std(ws)), transform=ax.transAxes, ) ax.set_xlabel("Longitude $^\circ$E") ax.set_ylabel("Latitude $^\circ$N") ax.set_xlim(-94.832, -94.673) ax.set_ylim(42.545, 42.671) ax.get_xaxis().set_ticks([]) ax.get_yaxis().set_ticks([]) # Next plot ax2 = fig.add_axes([0.7, 0.80, 0.28, 0.18]) ax2.scatter(ws, vals, edgecolor="k", c="k") ax2.text( 0.5, -0.25, "Wind Speed $ms^{-1}$", transform=ax2.transAxes, ha="center", ) ax2.set_xlim(0, 20) # ax2.set_ylabel("Power kW") ax2.grid(True) # Next plot ax3 = fig.add_axes([0.7, 0.57, 0.28, 0.18], sharey=ax2) ax3.scatter(yaw, vals, edgecolor="k", c="k") ax3.text(0.5, -0.25, "Yaw", transform=ax3.transAxes, ha="center") # ax3.set_ylabel("Power kW") ax3.set_xlim(0, 360) ax3.set_xticks(np.arange(0, 361, 45)) ax3.set_xticklabels(["N", "NE", "E", "SE", "S", "SW", "W", "NW", "N"]) ax3.grid(True) # Next plot ax4 = fig.add_axes([0.7, 0.32, 0.28, 0.18], sharey=ax2) ax4.scatter(pitch, vals, edgecolor="k", c="k") ax4.text(0.5, -0.25, "Pitch $^\circ$", transform=ax4.transAxes, ha="center") ax4.set_ylim(-10, 1600) ax4.grid(True) # Next plot ax5 = fig.add_axes([0.7, 0.07, 0.28, 0.18], sharex=ax4) ax5.scatter(pitch, ws, edgecolor="k", c="k") ax5.text(0.5, -0.25, "Pitch $^\circ$", transform=ax5.transAxes, ha="center") ax5.grid(True) ax5.set_ylim(bottom=-10) # maxpitch = max(np.where(pitch > 20, 0, pitch)) # ax5.set_xlim(np.ma.minimum(pitch)-0.5, maxpitch+0.5) ax5.set_xlim(-3, 20.1) ax5.set_ylim(0, 20) ax5.text( -0.1, 0.5, "Wind Speed $ms^{-1}$", transform=ax5.transAxes, ha="center", va="center", rotation=90, )
def simple(grids, valid, iarchive): """Simple gridder (stub for now)""" if iarchive: pgconn = psycopg2.connect(database='asos', host='iemdb', user='******') df = read_sql(""" SELECT ST_x(geom) as lon, ST_y(geom) as lat, tmpf, dwpf, sknt, drct, vsby from alldata c JOIN stations t on (c.station = t.id) WHERE c.valid >= %s and c.valid < %s and t.network in ('IA_ASOS', 'AWOS', 'MN_ASOS', 'WI_ASOS', 'IL_ASOS', 'MO_ASOS', 'NE_ASOS', 'KS_ASOS', 'SD_ASOS') and sknt is not null and drct is not null and tmpf is not null and dwpf is not null and vsby is not null """, pgconn, params=((valid - datetime.timedelta(minutes=30)), (valid + datetime.timedelta(minutes=30))), index_col=None) else: pgconn = psycopg2.connect(database='iem', host='iemdb', user='******') df = read_sql(""" SELECT ST_x(geom) as lon, ST_y(geom) as lat, tmpf, dwpf, sknt, drct, vsby from current c JOIN stations t on (c.iemid = t.iemid) WHERE c.valid > now() - '1 hour'::interval and t.network in ('IA_ASOS', 'AWOS', 'MN_ASOS', 'WI_ASOS', 'IL_ASOS', 'MO_ASOS', 'NE_ASOS', 'KS_ASOS', 'SD_ASOS') and sknt is not null and drct is not null and tmpf is not null and dwpf is not null and vsby is not null """, pgconn, index_col=None) if len(df.index) < 5: print(("i5gridder abort len(data): %s for %s iarchive: %s" % (len(df.index), valid, iarchive))) sys.exit() nn = NearestNDInterpolator((df['lon'].values, df['lat'].values), temperature(df['tmpf'].values, 'F').value('C')) grids['tmpc'] = nn(XI, YI) nn = NearestNDInterpolator((df['lon'].values, df['lat'].values), temperature(df['dwpf'].values, 'F').value('C')) grids['dwpc'] = nn(XI, YI) nn = NearestNDInterpolator((df['lon'].values, df['lat'].values), speed(df['sknt'].values, 'KT').value('MPS')) grids['smps'] = nn(XI, YI) u, v = meteorology.uv(speed(df['sknt'].values, 'KT'), direction(df['drct'].values, 'DEG')) nn = NearestNDInterpolator((df['lon'].values, df['lat'].values), u.value('MPS')) ugrid = nn(XI, YI) nn = NearestNDInterpolator((df['lon'].values, df['lat'].values), v.value('MPS')) vgrid = nn(XI, YI) drct = meteorology.drct(speed(ugrid.ravel(), 'MPS'), speed(vgrid.ravel(), 'MPS')).value('DEG').astype('i') grids['drct'] = np.reshape(drct, (len(YAXIS), len(XAXIS))) nn = NearestNDInterpolator((df['lon'].values, df['lat'].values), distance(df['vsby'].values, 'MI').value('KM')) grids['vsby'] = nn(XI, YI)
def plot_station(self, data, **kwargs): """Plot values on a map in a station plot like manner. Args: data (list): list of dicts with station data to plot fontsize (int): font size to use for plotted text """ (x0, x1) = self.ax.set_xlim() # size to use for circles circlesz = (x1 - x0) / 180. # (y0, y1) = self.ax.set_ylim() offsets = {1: [-4, 4, 'right', 'bottom'], 2: [0, 4, 'center', 'bottom'], 3: [4, 4, 'left', 'bottom'], 4: [-4, 0, 'right', 'center'], 5: [0, 0, 'center', 'center'], 6: [4, 0, 'left', 'center'], 7: [-4, -4, 'right', 'top'], 8: [0, -4, 'center', 'top'], 9: [4, -4, 'left', 'top']} mask = np.zeros(self.fig.canvas.get_width_height(), bool) for stdata in data: (x, y) = self.ax.projection.transform_point(stdata['lon'], stdata['lat'], ccrs.Geodetic()) (imgx, imgy) = self.ax.transData.transform([x, y]) imgx = int(imgx) imgy = int(imgy) # Check to see if this overlaps _cnt = np.sum(np.where(mask[imgx-15:imgx+15, imgy-15:imgy+15], 1, 0)) if _cnt > 5: continue mask[imgx-15:imgx+15, imgy-15:imgy+15] = True # Plot bars if stdata.get('sknt') is not None and stdata['sknt'] > 1: (u, v) = meteorology.uv(speed(stdata.get('sknt', 0), 'KT'), direction(stdata.get('drct', 0), 'DEG')) if u is not None and v is not None: self.ax.barbs(x, y, u.value('KT'), v.value('KT'), zorder=1) # Sky Coverage skycoverage = stdata.get('coverage') if (skycoverage is not None and skycoverage >= 0 and skycoverage <= 100): w = Wedge((x, y), circlesz, 0, 360, ec='k', fc='white', zorder=2) self.ax.add_artist(w) w = Wedge((x, y), circlesz, 0, 360. * skycoverage / 100., ec='k', fc='k', zorder=3) self.ax.add_artist(w) # Temperature val = stdata.get('tmpf') if val is not None: (offx, offy, ha, va) = offsets[1] self.ax.annotate( stdata.get("tmpf_format", "%.0f") % (val, ), xy=(x, y), ha=ha, va=va, xytext=(offx, offy), color=stdata.get('tmpf_color', 'r'), textcoords="offset points", zorder=Z_OVERLAY+2, clip_on=True, fontsize=kwargs.get('fontsize', 8)) # Dew Point val = stdata.get('dwpf') if val is not None: (offx, offy, ha, va) = offsets[7] self.ax.annotate( stdata.get("dwpf_format", "%.0f") % (val, ), xy=(x, y), ha=ha, va=va, xytext=(offx, offy), color=stdata.get('dwpf_color', 'b'), textcoords="offset points", zorder=Z_OVERLAY+2, clip_on=True, fontsize=kwargs.get('fontsize', 8)) # Plot identifier val = stdata.get('id') if val is not None: (offx, offy, ha, va) = ( offsets[6] if skycoverage is not None else offsets[5] ) self.ax.annotate( "%s" % (val, ), xy=(x, y), ha=ha, va=va, xytext=(offx, offy), color=stdata.get('id_color', 'tan'), textcoords="offset points", zorder=Z_OVERLAY+2, clip_on=True, fontsize=kwargs.get('fontsize', 8))
def plotter(fdict): """ Go """ pgconn = get_dbconn("asos") ctx = get_autoplot_context(fdict, get_description()) station = ctx["zstation"] units = ctx["units"] df = read_sql( """ select date_trunc('hour', valid at time zone 'UTC') as ts, avg(sknt) as sknt, max(drct) as drct from alldata WHERE station = %s and sknt is not null and drct is not null GROUP by ts """, pgconn, params=(station, ), index_col=None, ) if df.empty: raise NoDataFound("No Data Found.") sknt = speed(df["sknt"].values, "KT") drct = direction(df["drct"].values, "DEG") df["u"], df["v"] = [x.value("MPS") for x in meteorology.uv(sknt, drct)] df["month"] = df["ts"].dt.month grp = df[["month", "u", "v", "sknt"]].groupby("month").mean() grp["u_%s" % (units, )] = speed(grp["u"].values, "KT").value(units.upper()) grp["v_%s" % (units, )] = speed(grp["u"].values, "KT").value(units.upper()) grp["sped_%s" % (units, )] = speed(grp["sknt"].values, "KT").value(units.upper()) drct = meteorology.drct(speed(grp["u"].values, "KT"), speed(grp["v"].values, "KT")) grp["drct"] = drct.value("DEG") maxval = grp["sped_%s" % (units, )].max() (fig, ax) = plt.subplots(1, 1) ax.barh(grp.index.values, grp["sped_%s" % (units, )].values, align="center") ax.set_xlabel("Average Wind Speed [%s]" % (UNITS[units], )) ax.set_yticks(grp.index.values) ax.set_yticklabels(calendar.month_abbr[1:]) ax.grid(True) ax.set_xlim(0, maxval * 1.2) for mon, row in grp.iterrows(): ax.text( maxval * 1.1, mon, drct2text(row["drct"]), ha="center", va="center", bbox=dict(color="white"), ) ax.text( row["sped_%s" % (units, )] * 0.98, mon, "%.1f" % (row["sped_%s" % (units, )], ), ha="right", va="center", bbox=dict(color="white", boxstyle="square,pad=0.03"), ) ax.set_ylim(12.5, 0.5) ax.set_title(("[%s] %s [%s-%s]\nMonthly Average Wind Speed and" " Vector Average Direction") % ( station, ctx["_nt"].sts[station]["name"], df["ts"].min().year, df["ts"].max().year, )) return fig, grp