def plotter(fdict): """ Go """ ctx = get_context(fdict) fig = plt.figure(figsize=(6, 7.2), facecolor="w", edgecolor="w") rect = [0.08, 0.1, 0.8, 0.8] ax = WindroseAxes(fig, rect, facecolor="w") fig.add_axes(ax) ax.bar( ctx["df"]["drct"].values, ctx["df"]["smph"].values, normed=True, bins=[0, 2, 5, 7, 10, 15, 20], opening=0.8, edgecolor="white", nsector=18, ) handles = [] for p in ax.patches_list: color = p.get_facecolor() handles.append( Rectangle((0, 0), 0.1, 0.3, facecolor=color, edgecolor="black")) legend = fig.legend( handles, ("2-5", "5-7", "7-10", "10-15", "15-20", "20+"), loc=(0.01, 0.03), ncol=6, title="Wind Speed [%s]" % ("mph", ), mode=None, columnspacing=0.9, handletextpad=0.45, ) plt.setp(legend.get_texts(), fontsize=10) plt.gcf().text(0.5, 0.99, ctx["plottitle"], fontsize=16, ha="center", va="top") plt.gcf().text( 0.95, 0.12, "n=%s" % (len(ctx["df"].index), ), verticalalignment="bottom", ha="right", ) return fig, ctx["df"]
def plotter(fdict): """ Go """ ctx = get_context(fdict) fig = plt.figure(figsize=(6, 7.2), facecolor='w', edgecolor='w') rect = [0.08, 0.1, 0.8, 0.8] ax = WindroseAxes(fig, rect, facecolor='w') fig.add_axes(ax) ax.bar(ctx['df']['drct'].values, ctx['df']['smph'].values, normed=True, bins=[0, 2, 5, 7, 10, 15, 20], opening=0.8, edgecolor='white', nsector=18) handles = [] for p in ax.patches_list: color = p.get_facecolor() handles.append( Rectangle((0, 0), 0.1, 0.3, facecolor=color, edgecolor='black')) legend = fig.legend(handles, ('2-5', '5-7', '7-10', '10-15', '15-20', '20+'), loc=(0.01, 0.03), ncol=6, title='Wind Speed [%s]' % ('mph', ), mode=None, columnspacing=0.9, handletextpad=0.45) plt.setp(legend.get_texts(), fontsize=10) plt.gcf().text(0.5, 0.99, ctx['plottitle'], fontsize=16, ha='center', va='top') plt.gcf().text(0.95, 0.12, "n=%s" % (len(ctx['df'].index), ), verticalalignment="bottom", ha='right') return fig, ctx['df']
def plotter(fdict): """ Go """ pgconn = get_dbconn('iem') ctx = get_autoplot_context(fdict, get_description()) sts = ctx['sts'] ets = ctx['ets'] varname = ctx['var'] df = read_sql(""" WITH data as ( SELECT valid, high - high_normal as high_delta, low - low_normal as low_delta, precip, snow from cli_data where valid >= %s and valid <= %s and substr(station, 1, 1) = 'K' ) SELECT valid, sum(case when high_delta > 0 then 1 else 0 end) as high_above, sum(case when high_delta = 0 then 1 else 0 end) as high_equal, sum(case when high_delta < 0 then 1 else 0 end) as high_below, sum(case when low_delta > 0 then 1 else 0 end) as low_above, sum(case when low_delta = 0 then 1 else 0 end) as low_equal, sum(case when low_delta < 0 then 1 else 0 end) as low_below, sum(case when precip > 0 then 1 else 0 end) as precip_above, sum(case when precip = 0 then 1 else 0 end) as precip_below, sum(case when snow > 0 then 1 else 0 end) as snow_above, sum(case when snow = 0 then 1 else 0 end) as snow_below from data GROUP by valid ORDER by valid ASC """, pgconn, params=(sts, ets), index_col='valid') if df.empty: raise NoDataFound('Error, no results returned!') for v in ['precip', 'snow']: if varname == v: xlabel = "<-- No %s %% | %s %% -->" % (v.capitalize(), v.capitalize()) df[v + '_count'] = df[v + '_above'] + df[v + '_below'] colors = ['r', 'b'] for v in ['high', 'low']: df[v + '_count'] = (df[v + '_above'] + df[v + '_below'] + df[v + '_equal']) if varname == v: xlabel = "<-- Below Average % | Above Average % -->" colors = ['b', 'r'] (fig, ax) = plt.subplots(1, 1) ax.barh(df.index.values, 0 - (df[varname + '_below'] / df[varname + '_count'] * 100.), fc=colors[0], ec=colors[0], align='center') ax.barh(df.index.values, df[varname + '_above'] / df[varname + '_count'] * 100., fc=colors[1], ec=colors[1], align='center') ax.set_xlim(-100, 100) ax.grid(True) ax.set_title(("Percentage of CONUS NWS First Order CLImate Sites\n" "(%s - %s) %s" ) % (sts.strftime("%-d %b %Y"), ets.strftime("%-d %b %Y"), MDICT.get(varname))) ax.set_xlabel(xlabel) ticks = [-100, -90, -75, -50, -25, -10, 0, 10, 25, 50, 75, 90, 100] ax.set_xticks(ticks) ax.set_xticklabels([abs(x) for x in ticks]) plt.setp(ax.get_xticklabels(), rotation=30) ax.set_position([0.2, 0.15, 0.75, 0.75]) return fig, df
def plotter(fdict): """ Go """ pgconn = get_dbconn('postgis') ctx = get_autoplot_context(fdict, get_description()) station = ctx['station'][:4] phenomena = ctx['phenomena'] significance = ctx['significance'] split = ctx['split'] opt = ctx['opt'] state = ctx['state'] nt = NetworkTable('WFO') wfolimiter = " wfo = '%s' " % (station, ) if opt == 'state': wfolimiter = " substr(ugc, 1, 2) = '%s' " % (state, ) if split == 'jan1': sql = """ SELECT extract(year from issue)::int as year, min(issue at time zone 'UTC') as min_issue, max(issue at time zone 'UTC') as max_issue, count(distinct wfo || eventid) from warnings where """ + wfolimiter + """ and phenomena = %s and significance = %s GROUP by year ORDER by year ASC """ else: sql = """ SELECT extract(year from issue - '6 months'::interval)::int as year, min(issue at time zone 'UTC') as min_issue, max(issue at time zone 'UTC') as max_issue, count(distinct wfo || eventid) from warnings where """ + wfolimiter + """ and phenomena = %s and significance = %s GROUP by year ORDER by year ASC """ df = read_sql(sql, pgconn, params=(phenomena, significance), index_col=None) if df.empty: raise ValueError("No data found for query") # Since many VTEC events start in 2005, we should not trust any # data that has its first year in 2005 if df['year'].min() == 2005: df = df[df['year'] > 2005] def myfunc(row): year = row[0] valid = row[1] if year == valid.year: return int(valid.strftime("%j")) else: days = (datetime.date(year + 1, 1, 1) - datetime.date(year, 1, 1)).days return int(valid.strftime("%j")) + days df['startdoy'] = df[['year', 'min_issue']].apply(myfunc, axis=1) df['enddoy'] = df[['year', 'max_issue']].apply(myfunc, axis=1) df.set_index('year', inplace=True) # allow for small bars when there is just one event df.loc[df['enddoy'] == df['startdoy'], 'enddoy'] = df['enddoy'] + 1 ends = df['enddoy'].values starts = df['startdoy'].values years = df.index.values fig = plt.figure(figsize=(8, 6)) ax = plt.axes([0.1, 0.1, 0.7, 0.8]) ax.barh(years, (ends - starts), left=starts, fc='blue', align='center') ax.axvline(np.average(starts[:-1]), lw=2, color='red') ax.axvline(np.average(ends[:-1]), lw=2, color='red') ax.set_xlabel(("Avg Start Date: %s, End Date: %s") % ((datetime.date(2000, 1, 1) + datetime.timedelta( days=int(np.average(starts[:-1])))).strftime("%-d %b"), (datetime.date(2000, 1, 1) + datetime.timedelta( days=int(np.average(ends[:-1])))).strftime("%-d %b")), color='red') title = "[%s] NWS %s" % (station, nt.sts[station]['name']) if opt == 'state': title = ("NWS Issued Alerts for State of %s") % ( reference.state_names[state], ) ax.set_title(("%s\nPeriod between First and Last %s") % (title, vtec.get_ps_string(phenomena, significance))) ax.grid() days = [1, 32, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335] days = days + [x + 365 for x in days] ax.set_xticks(days) ax.set_xticklabels(calendar.month_abbr[1:] + calendar.month_abbr[1:]) ax.set_xlim(df['startdoy'].min() - 10, df['enddoy'].max() + 10) ax.set_ylabel("Year") ax.set_ylim(years[0] - 0.5, years[-1] + 0.5) xFormatter = FormatStrFormatter('%d') ax.yaxis.set_major_formatter(xFormatter) ax = plt.axes([0.82, 0.1, 0.13, 0.8]) ax.barh(years, df['count'], fc='blue', align='center') ax.set_ylim(years[0] - 0.5, years[-1] + 0.5) plt.setp(ax.get_yticklabels(), visible=False) ax.grid(True) ax.set_xlabel("# Events") ax.yaxis.set_major_formatter(xFormatter) xloc = plt.MaxNLocator(3) ax.xaxis.set_major_locator(xloc) return fig, df
def plotter(fdict): """ Go """ pgconn = get_dbconn("asos") ctx = get_autoplot_context(fdict, get_description()) station = ctx["zstation"] syear = ctx["syear"] eyear = ctx["eyear"] groupby = ctx["groupby"] sts = datetime.date(syear, 1, 1) ets = datetime.date(eyear + 1, 1, 1) code = ctx["code"] if code == "PSN": code = "+SN" PDICT["+SN"] = PDICT["PSN"] if groupby == "week": data = np.ma.zeros((24, 52), "f") df = read_sql( """ WITH data as ( SELECT valid at time zone %s + '10 minutes'::interval as v from alldata where station = %s and array_to_string(wxcodes, '') LIKE '%%""" + code + """%%' and valid > %s and valid < %s), agg as ( SELECT distinct extract(week from v)::int as week, extract(doy from v)::int as doy, extract(year from v)::int as year, extract(hour from v)::int as hour from data) SELECT week, year, hour, count(*) from agg WHERE week < 53 GROUP by week, year, hour """, pgconn, params=(ctx["_nt"].sts[station]["tzname"], station, sts, ets), index_col=None, ) else: data = np.ma.zeros((24, 366), "f") df = read_sql( """ WITH data as ( SELECT valid at time zone %s + '10 minutes'::interval as v from alldata where station = %s and array_to_string(wxcodes, '') LIKE '%%""" + code + """%%' and valid > %s and valid < %s), agg as ( SELECT distinct extract(doy from v)::int as doy, extract(year from v)::int as year, extract(hour from v)::int as hour from data) SELECT doy, year, hour, count(*) from agg GROUP by doy, year, hour """, pgconn, params=(ctx["_nt"].sts[station]["tzname"], station, sts, ets), index_col=None, ) if df.empty: raise NoDataFound("No data was found, sorry!") minyear = df["year"].min() maxyear = df["year"].max() for _, row in df.iterrows(): data[row["hour"], row[groupby] - 1] += 1 data.mask = np.where(data == 0, True, False) fig = plt.figure(figsize=(8, 6)) ax = plt.axes([0.11, 0.25, 0.7, 0.65]) cax = plt.axes([0.82, 0.04, 0.02, 0.15]) res = ax.imshow( data, aspect="auto", rasterized=True, interpolation="nearest" ) fig.colorbar(res, cax=cax) xloc = plt.MaxNLocator(4) cax.yaxis.set_major_locator(xloc) cax.set_ylabel("Count") ax.set_ylim(-0.5, 23.5) ax.set_yticks((0, 4, 8, 12, 16, 20)) ax.set_ylabel("Local Time, %s" % (ctx["_nt"].sts[station]["tzname"],)) ax.set_yticklabels(("Mid", "4 AM", "8 AM", "Noon", "4 PM", "8 PM")) ax.set_title( ("[%s] %s %s Reports\n[%.0f - %.0f]" " by hour and %s") % ( station, ctx["_nt"].sts[station]["name"], PDICT[code], minyear, maxyear, PDICT2[groupby].replace("group ", ""), ) ) ax.grid(True) lax = plt.axes([0.11, 0.1, 0.7, 0.15]) if groupby == "week": ax.set_xticks(np.arange(0, 55, 7)) lax.bar(np.arange(0, 52), np.ma.sum(data, 0), facecolor="tan") lax.set_xlim(-0.5, 51.5) lax.set_xticks(np.arange(0, 55, 7)) lax.set_xticklabels( ( "Jan 1", "Feb 19", "Apr 8", "May 27", "Jul 15", "Sep 2", "Oct 21", "Dec 9", ) ) else: ax.set_xticks( [1, 32, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 365] ) lax.bar(np.arange(0, 366), np.ma.sum(data, 0), facecolor="tan") lax.set_xlim(-0.5, 365.5) lax.set_xticks( [1, 32, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 365] ) lax.set_xticklabels(calendar.month_abbr[1:]) plt.setp(ax.get_xticklabels(), visible=False) # Bottom grid lax.grid(True) yloc = plt.MaxNLocator(3) lax.yaxis.set_major_locator(yloc) lax.yaxis.get_major_ticks()[-1].label1.set_visible(False) # Right grid rax = plt.axes([0.81, 0.25, 0.15, 0.65]) rax.barh(np.arange(0, 24) - 0.4, np.ma.sum(data, 1), facecolor="tan") rax.set_ylim(-0.5, 23.5) rax.set_yticks([]) xloc = plt.MaxNLocator(3) rax.xaxis.set_major_locator(xloc) rax.xaxis.get_major_ticks()[0].label1.set_visible(False) rax.grid(True) return fig, df
def plotter(fdict): """ Go """ ctx = get_autoplot_context(fdict, get_description()) station = ctx['station'] network = ctx['network'] sdate = ctx.get('sdate') plot_type = ctx['p'] nt = NetworkTable(network) if not nt.sts: raise ValueError( ("Network Identifier %s is unknown to IEM") % (network, )) if station not in nt.sts: raise ValueError( ("Station %s does not exist in network %s") % (station, network)) tzname = nt.sts[station]['tzname'] df = get_data(network, station, tzname, sdate) if df.empty: raise ValueError("No data was found!") # if d1 is not None and d1 >= 0 and d1 <= 360: # if s is not None and s >= 0 and s < 200: # if t is not None and t >= -90 and t < 190: # if d is not None and d >= -90 and d < 190: # if v1 is not None and v1 >= 0 and v1 < 30: def ceilingfunc(row): """Our logic to compute a ceiling""" c = [row['skyc1'], row['skyc2'], row['skyc3'], row['skyc4']] if 'OVC' in c: pos = c.index('OVC') larr = [row['skyl1'], row['skyl2'], row['skyl3'], row['skyl4']] return larr[pos] / 1000. df['ceiling'] = df.apply(ceilingfunc, axis=1) fig = plt.figure(figsize=(9, 9)) xalign = 0.1 xwidth = 0.8 ax = fig.add_axes([xalign, 0.7, xwidth, 0.25]) xmin = df.index.min() xmax = df.index.max() # ____________PLOT 1___________________________ df2 = df[df['tmpf'].notnull()] ax.plot(df2.index.values, df2['tmpf'], lw=2, label='Air Temp', color='#db6065', zorder=2) df2 = df[df['dwpf'].notnull()] ax.plot(df2.index.values, df2['dwpf'], lw=2, label='Dew Point', color='#346633', zorder=3) ax.set_title("[%s] %s\nRecent Time Series" % (station, nt.sts[station]['name'])) ax.grid(True) ax.text(-0.1, 0, "Temperature [F]", rotation=90, transform=ax.transAxes, verticalalignment='bottom') ax.set_ylim(bottom=(df['dwpf'].min() - 3)) plt.setp(ax.get_xticklabels(), visible=True) date_ticker(ax, pytz.timezone(tzname)) ax.set_xlim(xmin, xmax) ax.legend(loc='best', ncol=2) # _____________PLOT 2____________________________ ax = fig.add_axes([xalign, 0.4, xwidth, 0.25]) df2 = df[df['drct'].notnull()] ax2 = ax.twinx() df2 = df[df['gust'].notnull()] if not df2.empty: ax2.fill_between(df2.index.values, 0, dt.speed(df2['gust'], 'KT').value('MPH'), color='#9898ff', zorder=2) df2 = df[df['sknt'].notnull()] if not df2.empty: ax2.fill_between(df2.index.values, 0, dt.speed(df2['sknt'], 'KT').value('MPH'), color='#373698', zorder=3) ax2.set_ylim(bottom=0) ax.set_yticks(range(0, 361, 45)) ax.set_yticklabels(['N', 'NE', 'E', 'SE', 'S', 'SW', 'W', 'NW', "N"]) ax.set_ylabel("Wind Direction") ax2.set_ylabel("Wind Speed [mph]") ax.set_ylim(0, 360.1) date_ticker(ax, pytz.timezone(tzname)) ax.scatter(df2.index.values, df2['drct'], facecolor='None', edgecolor='#b8bc74', zorder=4) ax.set_zorder(ax2.get_zorder() + 1) ax.patch.set_visible(False) ax.set_xlim(xmin, xmax) # _________ PLOT 3 ____ ax = fig.add_axes([xalign, 0.1, xwidth, 0.25]) if plot_type == 'default': ax2 = ax.twinx() ax2.scatter(df.index.values, df['ceiling'], label='Visibility', marker='o', s=40, color='g') ax2.set_ylabel("Overcast Ceiling [k ft]", color='g') ax2.set_ylim(bottom=0) ax.scatter(df.index.values, df['vsby'], label='Visibility', marker='*', s=40, color='b') ax.set_ylabel("Visibility [miles]") ax.set_ylim(0, 14) elif plot_type == 'two': df2 = df[(df['alti'] > 20.) & (df['alti'] < 40.)] ax.grid(True) vals = dt.pressure(df2['alti'], 'IN').value('MB') ax.fill_between(df2.index.values, 0, vals, color='#a16334') ax.set_ylim(bottom=(vals.min() - 1), top=(vals.max() + 1)) ax.set_ylabel("Pressure [mb]") ax.set_xlim(xmin, xmax) date_ticker(ax, pytz.timezone(tzname)) ax.set_xlabel("Plot Time Zone: %s" % (tzname, )) return fig, df
def main(argv): """Do things""" dfs = [] for fn in glob.glob("/i/0/wb/07100004/0704/*"): df = read_wb(fn) df["fpath"] = int(fn.split("_")[1][:-3]) dfs.append(df) df = pd.concat(dfs) ranges = df.groupby(["fpath", "ofe"]).describe() year = 2018 for doy in tqdm(range(1, 365)): date = datetime.date(year, 1, 1) + datetime.timedelta(days=(doy - 1)) wb = df[(df["year"] == year) & (df["jday"] == doy)].copy() wb = wb.set_index(["fpath", "ofe"]) for f2 in ["sw1", "sw2", "sw"]: for f1 in ["min", "max"]: wb["%s_%s" % (f2, f1)] = ranges[f2, f1] wb["%s_range" % (f2, )] = (wb["%s_max" % (f2, )] - wb["%s_min" % (f2, )]) wb["%s_percent" % (f2, )] = ((wb[f2] - wb["%s_min" % (f2, )]) / wb["%s_range" % (f2, )] * 100.0) sns.set(style="white", palette="muted", color_codes=True) (fig, ax) = plt.subplots(3, 2, figsize=(7, 7)) sns.despine(left=True) fig.text( 0.5, 0.98, "%s :: Water Balance for 071000040704" % (date.strftime("%d %B %Y"), ), ha="center", ) # --------------------------------------------------- myax = ax[0, 0] sns.distplot(wb["sw1"], hist=False, color="g", ax=myax, rug=True) myax.set_xlabel("0-10cm Soil Water [mm]") myax.axvline(wb["sw1"].mean(), color="r") myax.set_xlim(0, 60) myax = ax[0, 1] sns.distplot(wb["sw1_percent"], hist=False, color="g", ax=myax, rug=True) myax.set_xlabel("0-10cm Soil Water of Capacity [%]") myax.axvline(wb["sw1_percent"].mean(), color="r") myax.set_xlim(0, 100) # --------------------------------------------------------- myax = ax[1, 0] sns.distplot(wb["sw2"], hist=False, color="g", ax=myax, rug=True) myax.set_xlabel("10-20cm Soil Water [mm]") myax.axvline(wb["sw2"].mean(), color="r") myax.set_xlim(0, 60) myax = ax[1, 1] sns.distplot(wb["sw2_percent"], hist=False, color="g", ax=myax, rug=True) myax.set_xlabel("10-20cm Soil Water of Capacity [%]") myax.axvline(wb["sw2_percent"].mean(), color="r") myax.set_xlim(0, 100) # ------------------------------------------------------- myax = ax[2, 0] sns.distplot(wb["sw"], hist=False, color="g", ax=myax, rug=True) myax.set_xlabel("Total Soil Water [mm]") myax.axvline(wb["sw"].mean(), color="r") myax.set_xlim(150, 650) myax = ax[2, 1] sns.distplot(wb["sw_percent"], hist=False, color="g", ax=myax, rug=True) myax.set_xlabel("Total Soil Water of Capacity [%]") myax.axvline(wb["sw_percent"].mean(), color="r") myax.set_xlim(0, 100) plt.setp(ax, yticks=[]) plt.tight_layout() fig.savefig("frames/%05i.png" % (doy - 1, )) plt.close()
def plotter(fdict): """ Go """ pgconn = get_dbconn('coop') ctx = get_autoplot_context(fdict, get_description()) station = ctx['station'] table = "alldata_%s" % (station[:2], ) nt = network.Table("%sCLIMATE" % (station[:2], )) today = datetime.datetime.now() thisyear = today.year df = read_sql(""" with data as ( select year, month, extract(doy from day) as doy, generate_series(32, high) as t from """ + table + """ where station = %s and year < %s), agger as ( SELECT year, t, min(doy), max(doy) from data GROUP by year, t) SELECT t as tmpf, avg(min) as min_jday, avg(max) as max_jday from agger GROUP by t ORDER by t ASC """, pgconn, params=(station, thisyear), index_col='tmpf') if df.empty: raise NoDataFound("No Data Found.") fig = plt.figure(figsize=(8, 6)) ax = plt.axes([0.1, 0.1, 0.7, 0.8]) ax2 = plt.axes([0.81, 0.1, 0.15, 0.8]) height = df['min_jday'][:] + 365. - df['max_jday'] ax2.plot(height, df.index.values) ax2.set_xticks([30, 90, 180, 365]) plt.setp(ax2.get_yticklabels(), visible=False) ax2.set_ylim(32, df.index.values.max() + 5) ax2.grid(True) ax2.text(0.96, 0.02, "Days", transform=ax2.transAxes, bbox=dict(color='white'), ha='right') ax.text(0.96, 0.02, "Period", transform=ax.transAxes, bbox=dict(color='white'), ha='right') ax.set_ylim(32, df.index.values.max() + 5) ax.barh(df.index.values - 0.5, height, left=df['max_jday'].values, ec='tan', fc='tan', height=1.1) days = np.array([1, 32, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335]) days = np.concatenate([days, days + 365]) ax.set_xticks(days) months = calendar.month_abbr[1:] + calendar.month_abbr[1:] ax.set_xticklabels(months) ax.set_ylabel("High Temperature $^\circ$F") ax.set_xlim(min(df['max_jday']) - 1, max(df['max_jday'] + height) + 1) ax.grid(True) msg = ("[%s] %s Period Between Average Last and " "First High Temperature of Year") % (station, nt.sts[station]['name']) tokens = msg.split() sz = int(len(tokens) / 2) ax.set_title(" ".join(tokens[:sz]) + "\n" + " ".join(tokens[sz:])) return fig, df
def plotter(fdict): """ Go """ ctx = get_autoplot_context(fdict, get_description()) station = ctx["station"] sdate = ctx.get("sdate") plot_type = ctx["p"] if not ctx["_nt"].sts: raise NoDataFound( ("Network Identifier %s is unknown to IEM") % (ctx["network"], )) tzname = ctx["_nt"].sts[station]["tzname"] df = get_data(ctx["network"], station, tzname, sdate) if df.empty: raise NoDataFound("No data was found!") # if d1 is not None and d1 >= 0 and d1 <= 360: # if s is not None and s >= 0 and s < 200: # if t is not None and t >= -90 and t < 190: # if d is not None and d >= -90 and d < 190: # if v1 is not None and v1 >= 0 and v1 < 30: def ceilingfunc(row): """Our logic to compute a ceiling""" c = [row["skyc1"], row["skyc2"], row["skyc3"], row["skyc4"]] if "OVC" in c: pos = c.index("OVC") larr = [row["skyl1"], row["skyl2"], row["skyl3"], row["skyl4"]] return larr[pos] / 1000.0 df["ceiling"] = df.apply(ceilingfunc, axis=1) fig = plt.figure(figsize=(9, 9)) xalign = 0.1 xwidth = 0.8 ax = fig.add_axes([xalign, 0.7, xwidth, 0.25]) xmin = df.index.min() xmax = df.index.max() # ____________PLOT 1___________________________ df2 = df[df["tmpf"].notnull()] ax.plot( df2.index.values, df2["tmpf"], lw=2, label="Air Temp", color="#db6065", zorder=2, ) df2 = df[df["dwpf"].notnull()] ax.plot( df2.index.values, df2["dwpf"], lw=2, label="Dew Point", color="#346633", zorder=3, ) ax.set_title("[%s] %s\nRecent Time Series" % (station, ctx["_nt"].sts[station]["name"])) ax.grid(True) ax.text( -0.1, 0, "Temperature [F]", rotation=90, transform=ax.transAxes, verticalalignment="bottom", ) ax.set_ylim(bottom=(df["dwpf"].min() - 3)) plt.setp(ax.get_xticklabels(), visible=True) date_ticker(ax, pytz.timezone(tzname)) ax.set_xlim(xmin, xmax) ax.legend(loc="best", ncol=2) # _____________PLOT 2____________________________ ax = fig.add_axes([xalign, 0.4, xwidth, 0.25]) ax2 = ax.twinx() df2 = df[df["gust"].notnull()] if not df2.empty: ax2.fill_between( df2.index.values, 0, (df2["gust"].values * units("knot")).to(units("mile / hour")).m, color="#9898ff", zorder=2, ) df2 = df[df["sknt"].notnull()] if not df2.empty: ax2.fill_between( df2.index.values, 0, (df2["sknt"].values * units("knot")).to(units("mile / hour")).m, color="#373698", zorder=3, ) ax2.set_ylim(bottom=0) ax.set_yticks(range(0, 361, 45)) ax.set_yticklabels(["N", "NE", "E", "SE", "S", "SW", "W", "NW", "N"]) ax.set_ylabel("Wind Direction") ax2.set_ylabel("Wind Speed [mph]") ax.set_ylim(0, 360.1) date_ticker(ax, pytz.timezone(tzname)) ax.scatter( df2.index.values, df2["drct"], facecolor="None", edgecolor="#b8bc74", zorder=4, ) ax.set_zorder(ax2.get_zorder() + 1) ax.patch.set_visible(False) ax.set_xlim(xmin, xmax) # _________ PLOT 3 ____ ax = fig.add_axes([xalign, 0.1, xwidth, 0.25]) if plot_type == "default": ax2 = ax.twinx() ax2.scatter( df.index.values, df["ceiling"], label="Visibility", marker="o", s=40, color="g", ) ax2.set_ylabel("Overcast Ceiling [k ft]", color="g") ax2.set_ylim(bottom=0) ax.scatter( df.index.values, df["vsby"], label="Visibility", marker="*", s=40, color="b", ) ax.set_ylabel("Visibility [miles]") ax.set_ylim(0, 14) elif plot_type == "two": df2 = df[(df["alti"] > 20.0) & (df["alti"] < 40.0)] ax.grid(True) vals = (df2["alti"].values * units("inch_Hg")).to(units("hPa")).m ax.fill_between(df2.index.values, 0, vals, color="#a16334") ax.set_ylim(bottom=(vals.min() - 1), top=(vals.max() + 1)) ax.set_ylabel("Pressure [mb]") ax.set_xlim(xmin, xmax) date_ticker(ax, pytz.timezone(tzname)) ax.set_xlabel("Plot Time Zone: %s" % (tzname, )) return fig, df
def plotter(fdict): """ Go """ pgconn = get_dbconn('asos') ctx = get_autoplot_context(fdict, get_description()) station = ctx['zstation'] network = ctx['network'] syear = ctx['syear'] eyear = ctx['eyear'] groupby = ctx['groupby'] sts = datetime.date(syear, 1, 1) ets = datetime.date(eyear + 1, 1, 1) nt = NetworkTable(network) code = ctx['code'] if code == 'PSN': code = "+SN" PDICT['+SN'] = PDICT['PSN'] if groupby == 'week': data = np.ma.zeros((24, 52), 'f') df = read_sql(""" WITH data as ( SELECT valid at time zone %s + '10 minutes'::interval as v from alldata where station = %s and array_to_string(wxcodes, '') LIKE '%%""" + code + """%%' and valid > %s and valid < %s), agg as ( SELECT distinct extract(week from v)::int as week, extract(doy from v)::int as doy, extract(year from v)::int as year, extract(hour from v)::int as hour from data) SELECT week, year, hour, count(*) from agg WHERE week < 53 GROUP by week, year, hour """, pgconn, params=(nt.sts[station]['tzname'], station, sts, ets), index_col=None) else: data = np.ma.zeros((24, 366), 'f') df = read_sql(""" WITH data as ( SELECT valid at time zone %s + '10 minutes'::interval as v from alldata where station = %s and array_to_string(wxcodes, '') LIKE '%%""" + code + """%%' and valid > %s and valid < %s), agg as ( SELECT distinct extract(doy from v)::int as doy, extract(year from v)::int as year, extract(hour from v)::int as hour from data) SELECT doy, year, hour, count(*) from agg GROUP by doy, year, hour """, pgconn, params=(nt.sts[station]['tzname'], station, sts, ets), index_col=None) if df.empty: raise ValueError("No data was found, sorry!") minyear = df['year'].min() maxyear = df['year'].max() for _, row in df.iterrows(): data[row['hour'], row[groupby] - 1] += 1 data.mask = np.where(data == 0, True, False) fig = plt.figure(figsize=(8, 6)) ax = plt.axes([0.11, 0.25, 0.7, 0.65]) cax = plt.axes([0.82, 0.04, 0.02, 0.15]) res = ax.imshow(data, aspect='auto', rasterized=True, interpolation='nearest') fig.colorbar(res, cax=cax) xloc = plt.MaxNLocator(4) cax.yaxis.set_major_locator(xloc) cax.set_ylabel("Count") ax.set_ylim(-0.5, 23.5) ax.set_yticks((0, 4, 8, 12, 16, 20)) ax.set_ylabel("Local Time, %s" % (nt.sts[station]['tzname'], )) ax.set_yticklabels(('Mid', '4 AM', '8 AM', 'Noon', '4 PM', '8 PM')) ax.set_title(("[%s] %s %s Reports\n[%.0f - %.0f]" " by hour and %s") % (station, nt.sts[station]['name'], PDICT[code], minyear, maxyear, PDICT2[groupby].replace("group ", ""))) ax.grid(True) lax = plt.axes([0.11, 0.1, 0.7, 0.15]) if groupby == 'week': ax.set_xticks(np.arange(0, 55, 7)) lax.bar(np.arange(0, 52), np.ma.sum(data, 0), facecolor='tan') lax.set_xlim(-0.5, 51.5) lax.set_xticks(np.arange(0, 55, 7)) lax.set_xticklabels(('Jan 1', 'Feb 19', 'Apr 8', 'May 27', 'Jul 15', 'Sep 2', 'Oct 21', 'Dec 9')) else: ax.set_xticks( [1, 32, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 365]) lax.bar(np.arange(0, 366), np.ma.sum(data, 0), facecolor='tan') lax.set_xlim(-0.5, 365.5) lax.set_xticks( [1, 32, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 365]) lax.set_xticklabels(calendar.month_abbr[1:]) plt.setp(ax.get_xticklabels(), visible=False) # Bottom grid lax.grid(True) yloc = plt.MaxNLocator(3) lax.yaxis.set_major_locator(yloc) lax.yaxis.get_major_ticks()[-1].label1.set_visible(False) # Right grid rax = plt.axes([0.81, 0.25, 0.15, 0.65]) rax.barh(np.arange(0, 24) - 0.4, np.ma.sum(data, 1), facecolor='tan') rax.set_ylim(-0.5, 23.5) rax.set_yticks([]) xloc = plt.MaxNLocator(3) rax.xaxis.set_major_locator(xloc) rax.xaxis.get_major_ticks()[0].label1.set_visible(False) rax.grid(True) return fig, df
def _make_plot(station, df, units, nsector, rmax, hours, months, sname, level, bins, **kwargs): """Generate a matplotlib windrose plot Args: station (str): station identifier df (pd.DataFrame): observations drct (list): list of wind directions units (str): units of wind speed nsector (int): number of bins to use for windrose rmax (float): radius of the plot hours (list): hour limit for plot month (list): month limit for plot sname (str): station name level (int): RAOB level in hPa of interest bins (list): values for binning the wind speeds Returns: matplotlib.Figure """ # Generate figure fig = plt.figure(figsize=(8, 8), dpi=100, facecolor='w', edgecolor='w') rect = [0.12, 0.12, 0.76, 0.76] ax = WindroseAxes(fig, rect, facecolor='w', rmax=rmax) fig.add_axes(ax) wu = WINDUNITS[units] if level is None else RAOB_WINDUNITS[units] if bins: wu['bins'] = bins wu['binlbl'] = [] for i, mybin in enumerate(bins[1:-1]): wu['binlbl'].append("%g-%g" % (mybin, bins[i + 2])) wu['binlbl'].append("%g+" % (bins[-1], )) # Filters the missing values df2 = df[df['drct'] >= 0] try: # Unsure why this bombs out sometimes ax.bar(df2['drct'].values, df2['speed'].values, normed=True, bins=wu['bins'], opening=0.8, edgecolor='white', nsector=nsector) except Exception as exp: sys.stderr.write(str(exp)) # Figure out the shortest bar mindir = ax._info['dir'][np.argmin(np.sum(ax._info['table'], axis=0))] ax.set_rlabel_position((450 - mindir) % 360 - 15) # Adjust the limits so to get a empty center rmin, rmax = ax.get_ylim() ax.set_rorigin(0 - (rmax - rmin) * 0.2) # Make labels have % formatters ax.yaxis.set_major_formatter(FormatStrFormatter('%.1f%%')) handles = [] for p in ax.patches_list: color = p.get_facecolor() handles.append( plt.Rectangle((0, 0), 0.1, 0.3, facecolor=color, edgecolor='black')) legend = fig.legend(handles, wu['binlbl'], bbox_to_anchor=(0.01, 0.01, 0.98, 0.09), loc='center', ncol=6, title='Wind Speed [%s]' % (wu['abbr'], ), mode=None, columnspacing=0.9, handletextpad=0.45, fontsize=14) plt.setp(legend.get_texts(), fontsize=10) # Now we put some fancy debugging info on the plot tlimit = "Time Domain: " if len(hours) == 24 and len(months) == 12: tlimit = "All Year" if len(hours) < 24: if len(hours) > 4: tlimit += "%s-%s" % ( datetime.datetime(2000, 1, 1, hours[0]).strftime("%-I %p"), datetime.datetime(2000, 1, 1, hours[-1]).strftime("%-I %p")) else: for h in hours: tlimit += "%s," % (datetime.datetime(2000, 1, 1, h).strftime("%-I %p"), ) if len(months) < 12: for h in months: tlimit += "%s," % (datetime.datetime(2000, h, 1).strftime("%b"), ) label = """[%s] %s%s Windrose Plot [%s] Period of Record: %s - %s""" % ( station, sname if sname is not None else "((%s))" % (station, ), "" if level is None else " @%s hPa" % (level, ), tlimit, df['valid'].min().strftime("%d %b %Y"), df['valid'].max().strftime("%d %b %Y")) plt.gcf().text(0.14, 0.99, label, va='top', fontsize=14) plt.gcf().text( 0.5, 0.5, "Calm\n%.1f%%" % (len(df[df['sknt'] == 0].index) / float(len(df2.index)) * 100., ), ha='center', va='center', fontsize=14) plt.gcf().text( 0.96, 0.11, ("Summary\nobs count: %s\nMissing: %s\nAvg Speed: %.1f %s") % (len(df.index), len(df.index) - len(df2.index), df['speed'].mean(), wu['abbr']), ha='right', fontsize=14) if not kwargs.get('nogenerated', False): plt.gcf().text(0.02, 0.1, "Generated: %s" % (datetime.datetime.now().strftime("%d %b %Y"), ), verticalalignment="bottom", fontsize=14) # Denote the direction blowing from plt.gcf().text(0.02, 0.125, "Direction is where the wind is\nblowing from, not toward.", va='bottom') # Make a logo im = mpimage.imread('%s/%s' % (DATADIR, 'logo.png')) plt.figimage(im, 10, 735) return fig