Skip to article frontmatterSkip to article content

Northwestern University (NU) Current Conditions

Source
from IPython.display import IFrame
import pandas as pd
import sage_data_client
import holoviews as hv
import hvplot.pandas
from metpy.units import units
import metpy.calc as mpcalc
from bokeh.models import DatetimeTickFormatter
import sage_data_client

hv.extension("bokeh")

def apply_formatter(plot, element):
    plot.handles['xaxis'].formatter = DatetimeTickFormatter(hours='%m/%d/%Y \n %l:%M %p',
                                                            minutes='%m/%d/%Y \n %l:%M %p',
                                                            hourmin='%m/%d/%Y \n %l:%M %p',
                                                            days='%m/%d/%Y \n %l:%M %p',
                                                            months='%m/%d/%Y \n %l:%M %p')

def add_local_time(df):
    df["Local_Time"] = pd.to_datetime(df.index,unit='s', utc=True)\
                          .map(lambda x: x.tz_convert('America/Chicago'))
    return df

def get_field_convert_to_degF(df, variable):
    subset = df.loc[df.name == variable]

    subset["value"] = (subset.value.values * units.degC).to("degF")
    return subset.value

def get_field(df, variable):
    subset = df.loc[df.name == variable]
    return subset.value

import warnings
warnings.filterwarnings('ignore')
Loading...

Temperature and Dewpoint

Source
wxt_df = sage_data_client.query(
    start="-12h", 
    filter={
        "vsn": "W099",
        "name": "wxt.env.temp|wxt.env.humidity"
    }
).set_index("timestamp")

temp_df = wxt_df.loc[wxt_df.name == "wxt.env.temp"]
hum_df = wxt_df.loc[wxt_df.name == "wxt.env.humidity"]

min_df = temp_df[["value"]].resample("1min").mean()
min_df["rh"] = hum_df[["value"]].resample("1min").mean()

min_df["tmpf"] = (min_df.value.values * units.degC).to("degF").m
min_df["dwpf"] = mpcalc.dewpoint_from_relative_humidity(min_df.tmpf.values * units.degF,
                                       min_df.rh.values * units.percent).to("degF").m

min_df = add_local_time(min_df)

temp_plot = min_df.hvplot(x='Local_Time',
                          y='tmpf',
                          color = "r",
                          label="Temperature [degF]"
                         )
dewp_plot = min_df.hvplot(x='Local_Time',
                          y='dwpf',
                          color="g",
                          title="Current Weather at Northwestern University (NU)",
                          label="Dewpoint [degF]",
                          ylabel="Temperature | Dewpoint \n [degF]",
                          xlabel="Local Time (Central/US)")

(temp_plot * dewp_plot).opts(hooks=[apply_formatter], legend_position='right')
Loading...

Air Quality

Source
df = sage_data_client.query(
    start="-12h", 
    filter={
        "vsn": "W099",
        "name": "aqt.particle.pm2.5"
    }
).set_index("timestamp")

df = add_local_time(df)[["value", "Local_Time"]].resample("5min").mean()

df.hvplot(label='PM 2.5 Values at Northwestern University (NU)',
          x='Local_Time',
          y='value',
          ylabel='PM 2.5 \n [microgram per cubic meter]',
          xlabel="Local Time (Central/US)").opts(hooks=[apply_formatter])
Loading...

Soil Temperature

Source
df = sage_data_client.query(
    start="-1d", 
    filter={
        "vsn": "W099",
        "name": "temp_d1|temp_d2|temp_d3|temp_d4",
        "deviceName": "MFR node MNLA4O104"
    }
).set_index("timestamp")

soil_temp_df = pd.DataFrame({"~6 inches below the surface": get_field_convert_to_degF(df, "temp_d1"),
                             "~1 feet below the surface": get_field_convert_to_degF(df, "temp_d2"),
                             "~1.5 feet below the surface": get_field_convert_to_degF(df, "temp_d3"),
                             "~2 feet below the surface": get_field_convert_to_degF(df, "temp_d4")})

soil_temp_df = add_local_time(soil_temp_df)

first = soil_temp_df.hvplot(ylabel="Soil Temperature [degF]",
                    xlabel="Time/Date",
                    x='Local_Time',
                    title="Soil Temperature at Northwestern University \n Grove Site").opts(hooks=[apply_formatter])

first
Loading...

Soil Moisture

Source
df = sage_data_client.query(
    start="-1d", 
    filter={
        "vsn": "W099",
        "name": "vwc_d1|vwc_d2|vwc_d3|vwc_d4",
        "deviceName": "MFR node MNLA4O104"
    }
).set_index("timestamp")

soil_temp_df = pd.DataFrame({"~6 inches below the surface": get_field(df, "vwc_d1"),
                             "~1 feet below the surface": get_field(df, "vwc_d2"),
                             "~1.5 feet below the surface": get_field(df, "vwc_d3"),
                             "~2 feet below the surface": get_field(df, "vwc_d4")})

soil_temp_df = add_local_time(soil_temp_df)

first = soil_temp_df.hvplot(ylabel="Soil Moisture [%]",
                    xlabel="Time/Date",
                    x='Local_Time',
                    title="Soil Moisture at Northwestern University \n Grove Site").opts(hooks=[apply_formatter])

first
Loading...

Water Depth

df = sage_data_client.query(
    start="-1d", 
    filter={
        "vsn": "W099",
        "name": "water_depth",
        "deviceName": "MFR node MNLA4O104"
    }
).set_index("timestamp")

df = add_local_time(df)

# Convert from mm to meters
df["value"] = df["value"]/1000.

first = df.hvplot(x='Local_Time',
          ylabel='Ground Water Height [meters]',
          xlabel="Date | Time",
          title="Ground Water Height at Northwestern University \n Grove Site").opts(hooks=[apply_formatter])
first
Loading...

Location

Observations the Northwestern University (NU) campus, on the rooftop of Scott Hall.

Rooftop Location - Scott Hall (Weather + Air Quality)

Source
IFrame("https://www.google.com/maps/embed?pb=!1m17!1m12!1m3!1d2954.899516515807!2d-87.68021728835393!3d42.05144087110307!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!3m2!1m1!2zNDLCsDAzJzA1LjIiTiA4N8KwNDAnMzkuNSJX!5e1!3m2!1sen!2sus!4v1745338549074!5m2!1sen!2sus", width=700, height=350)
Loading...