Skip to content
Snippets Groups Projects
Unverified Commit 02227946 authored by David Hoese's avatar David Hoese
Browse files

Fix auto date formatting for quicklooks

parent c751ef4e
No related branches found
No related tags found
No related merge requests found
import os
import sys
from datetime import datetime as dt, timedelta as delta
from datetime import datetime, timedelta
import logging
import pandas as pd
from netCDF4 import MFDataset, MFTime
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.dates as md
import math
LOG = logging.getLogger(__name__)
......@@ -27,7 +28,7 @@ class PlotMaker(object):
self.deps = dependencies
self._full_figure = None
if title is None:
title = "{title_prefix}{title_name}{units} {start_time:%Y-%m-%d}"
title = "{title_prefix}{title_name}{units}\n{date_string}"
self._title = title
self.units = units
......@@ -37,24 +38,32 @@ class PlotMaker(object):
if var_name not in frame:
yield var_name
def get_title(self, frame, is_subplot):
def get_date_string(self, start_time, end_time):
delta = (end_time - start_time).total_seconds()
if delta < timedelta(hours=24).total_seconds():
return start_time.strftime("%Y-%m-%d")
else:
return "{:%Y-%m-%d %H:%M} to {:%Y-%m-%d %H:%M}".format(start_time, end_time)
def get_title(self, frame, is_subplot, start_time, end_time):
if self._title:
title_prefix = "AO&SS Building Tower " if not is_subplot else ''
title_name = TITLES.get(self.name, self.name.replace('_', ' ').title())
unit_str = '({})'.format(self.units) if self.units and is_subplot else ''
date_string = self.get_date_string(start_time, end_time)
title = self._title.format(title_prefix=title_prefix,
title_name=title_name,
units=unit_str,
start_time=frame.index[0].to_pydatetime())
date_string=date_string)
else:
title = ''
return title
def get_yticks(self, ymin, ymax, num_plots):
if ymin == ymax:
return [ymin, ymin + 0.05, ymin + 0.1]
delta = math.ceil((ymax - ymin) / num_plots)
new_ticks = np.arange(ymin, (ymin + delta * num_plots), delta)
if not new_ticks:
return [ymin, ymin + 0.05, ymin + 0.1]
return new_ticks
def get_ylabel(self, is_subplot=False):
......@@ -65,7 +74,8 @@ class PlotMaker(object):
return "{} ({})".format(y_label, self.units)
return y_label
def create_plot(self, frame, fig, is_subplot=None, shared_x=None, title=None):
def create_plot(self, frame, fig, start_time=None, end_time=None,
is_subplot=None, shared_x=None, title=None):
"""
:param frame:
......@@ -74,8 +84,12 @@ class PlotMaker(object):
:param shared_x:
:return:
"""
if start_time is None:
start_time = frame.index[0].to_pydatetime()
if end_time is None:
end_time = frame.index[-1].to_pydatetime()
if title is None:
title = self.get_title(frame, is_subplot)
title = self.get_title(frame, is_subplot, start_time, end_time)
if is_subplot:
ax = fig.add_subplot(*is_subplot, sharex=shared_x)
......@@ -114,11 +128,17 @@ class MeteorogramPlotMaker(PlotMaker):
self.plot_deps = plot_deps
super(MeteorogramPlotMaker, self).__init__(name, dependencies, title=title)
def create_plot(self, frame, fig, is_subplot=False, shared_x=None):
def create_plot(self, frame, fig, start_time=None, end_time=None,
is_subplot=False, shared_x=None, title=None):
if is_subplot or shared_x:
raise ValueError("Meteorogram Plot can not be a subplot or share X-axis")
title = self.get_title(frame, False)
if start_time is None:
start_time = frame.index[0].to_pydatetime()
if end_time is None:
end_time = frame.index[-1].to_pydatetime()
if title is None:
title = self.get_title(frame, False, start_time, end_time)
fig.suptitle(title, fontsize=13)
num_plots = len(self.plot_deps)
......@@ -137,6 +157,7 @@ class MeteorogramPlotMaker(PlotMaker):
ax.get_xaxis().get_major_ticks()[-1].set_visible(False)
ax.get_xaxis().get_major_ticks()[0].set_visible(False)
ax.set_xlabel('Time (UTC)')
fig.subplots_adjust(hspace=0, bottom=0.125)
return ax
......@@ -177,12 +198,12 @@ def get_data(input_files, columns):
# convert base_time epoch format into date_time object
base_time = files.variables['base_time'][:]
base_time_obj = dt(1970, 1, 1) + delta(seconds=int(base_time))
base_time_obj = datetime(1970, 1, 1) + timedelta(seconds=int(base_time))
# convert per-file offsets to offsets based on the first file's base_time
offsets = MFTime(files.variables['time_offset'])[:]
# for each offset, convert that into a datetime object
data_dict['stamps'] = [base_time_obj + delta(seconds=int(s)) for s in offsets]
data_dict['stamps'] = [base_time_obj + timedelta(seconds=int(s)) for s in offsets]
return pd.DataFrame(data_dict).set_index(['stamps'])
......@@ -197,7 +218,7 @@ def get_dates_in_range(cur_dt, end):
curr = cur_dt
while curr <= end:
yield curr
curr += delta(days=1)
curr += timedelta(days=1)
# The purpose of this method is to get the min and max of
# an array of stamps and determines all the 12:00:00 days
......@@ -220,7 +241,7 @@ def find_half_days(dewpoint_stamps, dates):
cur_dt = date_min.replace(hour=12, minute=0, second=0)
if cur_dt < date_min:
cur_dt += delta(days=1)
cur_dt += timedelta(days=1)
datesInRange = list(get_dates_in_range(cur_dt, date_max))
......@@ -467,6 +488,11 @@ def create_full_plot(plot_names, frame, output, start_time=None, end_time=None):
# numberPlots = len(list(frame.columns.values)) / 2
# plotNumber = numberPlots * 100 + 10
if start_time is None:
start_time = frame.index[0].to_pydatetime()
if end_time is None:
end_time = frame.index[-1].to_pydatetime()
for name in plot_names:
plot_maker = PLOT_TYPES.get(name, PlotMaker(name, (name,)))
var_names = []
......@@ -485,9 +511,8 @@ def create_full_plot(plot_names, frame, output, start_time=None, end_time=None):
plot_frame = plot_frame[~plot_frame.isnull().any(axis=1)]
fig = plt.figure()
ax = plot_maker.create_plot(plot_frame, fig)
ax = plot_maker.create_plot(plot_frame, fig, start_time=start_time, end_time=end_time)
ax.set_xlim(start_time, end_time)
import matplotlib.dates as md
xloc = md.AutoDateLocator(minticks=5, maxticks=8, interval_multiples=True)
xfmt = md.AutoDateFormatter(xloc)
def _fmt(interval, x, pos=None):
......@@ -495,7 +520,7 @@ def create_full_plot(plot_names, frame, output, start_time=None, end_time=None):
delta_seconds = (x_num - plot_frame.index[0].replace(hour=0, minute=0, second=0, microsecond=0)).total_seconds()
num_hours = delta_seconds / 3600.
if interval == md.HOURLY:
return "{:02.0f}".format(num_hours)
return "{:.0f}".format(num_hours)
elif interval == md.MINUTELY:
num_minutes = delta_seconds / 60.
num_minutes -= int(num_hours) * 60.
......@@ -508,7 +533,7 @@ def create_full_plot(plot_names, frame, output, start_time=None, end_time=None):
ax.xaxis.set_major_locator(xloc)
ax.xaxis.set_major_formatter(xfmt)
out_fn = output.format(plot_name=name, start_time=plot_frame.index[0].to_pydatetime())
out_fn = output.format(plot_name=name, start_time=start_time, end_time=end_time)
LOG.info("Saving plot '{}' to filename '{}'".format(name, out_fn))
fig.savefig(out_fn)
......@@ -556,9 +581,9 @@ def create_full_plot(plot_names, frame, output, start_time=None, end_time=None):
def _dt_convert(datetime_str):
try:
return dt.strptime(datetime_str, '%Y-%m-%dT%H:%M:%S')
return datetime.strptime(datetime_str, '%Y-%m-%dT%H:%M:%S')
except ValueError:
return dt.strptime(datetime_str, '%Y-%m-%d')
return datetime.strptime(datetime_str, '%Y-%m-%d')
def main():
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment