-
Notifications
You must be signed in to change notification settings - Fork 270
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Time-height displays. #453
Changes from all commits
ceee1f8
020e146
bd25ba4
493e51a
74c667d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,11 +17,15 @@ | |
import matplotlib.pyplot as plt | ||
import numpy as np | ||
import netCDF4 | ||
from matplotlib.dates import ( | ||
DateFormatter, SecondLocator, MinuteLocator, | ||
HourLocator, DayLocator) | ||
|
||
from . import common | ||
from ..core.transforms import antenna_to_cartesian | ||
from ..core.transforms import antenna_vectors_to_cartesian | ||
from ..core.transforms import corner_to_point | ||
from ..util.datetime_utils import datetimes_from_radar | ||
|
||
|
||
class RadarDisplay(object): | ||
|
@@ -486,7 +490,10 @@ def plot_vpt(self, field, mask_tuple=None, vmin=None, vmax=None, | |
axislabels=(None, None), axislabels_flag=True, | ||
colorbar_flag=True, colorbar_label=None, | ||
colorbar_orient='vertical', edges=True, | ||
filter_transitions=True, ax=None, fig=None): | ||
filter_transitions=True, | ||
time_axis_flag=False, | ||
date_time_form=None, tz=None, | ||
ax=None, fig=None): | ||
""" | ||
Plot a VPT scan. | ||
|
||
|
@@ -542,6 +549,15 @@ def plot_vpt(self, field, mask_tuple=None, vmin=None, vmax=None, | |
sweeps from the plot. False will include these rays in the plot. | ||
No rays are filtered when the antenna_transition attribute of the | ||
underlying radar is not present. | ||
time_axis_flag : bool | ||
True to plot the x-axis as time. False uses the index number. | ||
Default is False - index-based. | ||
date_time_form : str, optional | ||
Format of the time string for x-axis labels. Parameter is | ||
ignored if time_axis_flag is set to False. | ||
tz : str, optional | ||
Time zone info to use when creating axis labels (see datetime). | ||
Parameter is ignored if time_axis_flag is set to False. | ||
ax : Axis | ||
Axis to plot on. None will use the current axis. | ||
fig : Figure | ||
|
@@ -567,6 +583,11 @@ def plot_vpt(self, field, mask_tuple=None, vmin=None, vmax=None, | |
x = np.arange(data.shape[1]) | ||
y = self.ranges / 1000. | ||
|
||
# set up the time axis | ||
if time_axis_flag: | ||
self._set_vpt_time_axis(ax, date_time_form=date_time_form, tz=tz) | ||
x = datetimes_from_radar(radar) | ||
|
||
# mask the data where outside the limits | ||
if mask_outside: | ||
data = np.ma.masked_invalid(data) | ||
|
@@ -579,7 +600,7 @@ def plot_vpt(self, field, mask_tuple=None, vmin=None, vmax=None, | |
self._set_vpt_title(field, title, ax) | ||
|
||
if axislabels_flag: | ||
self._label_axes_vpt(axislabels, ax) | ||
self._label_axes_vpt(axislabels, time_axis_flag, ax) | ||
|
||
# add plot and field to lists | ||
self.plots.append(pm) | ||
|
@@ -933,6 +954,11 @@ def label_xaxis_rays(self, ax=None): | |
ax = common.parse_ax(ax) | ||
ax.set_xlabel('Ray number (unitless)') | ||
|
||
def label_xaxis_time(self, ax=None): | ||
""" Label the yaxis with the default label for rays. """ | ||
ax = common.parse_ax(ax) | ||
ax.set_xlabel('Time (HH:MM)') | ||
|
||
def label_yaxis_field(self, field, ax=None): | ||
""" Label the yaxis with the default label for a field units. """ | ||
ax = common.parse_ax(ax) | ||
|
@@ -1007,18 +1033,42 @@ def _label_axes_ray(self, axis_labels, field, ax): | |
else: | ||
ax.set_ylabel(y_label) | ||
|
||
def _label_axes_vpt(self, axis_labels, ax): | ||
def _label_axes_vpt(self, axis_labels, time_axis_flag, ax): | ||
""" Set the x and y axis labels for a PPI plot. """ | ||
x_label, y_label = axis_labels | ||
if x_label is None: | ||
self.label_xaxis_rays(ax) | ||
if time_axis_flag: | ||
self.label_xaxis_time(ax) | ||
else: | ||
self.label_xaxis_rays(ax) | ||
else: | ||
ax.set_xlabel(x_label) | ||
if y_label is None: | ||
self.label_yaxis_z(ax) | ||
else: | ||
ax.set_ylabel(y_label) | ||
|
||
def _set_vpt_time_axis(self, ax, date_time_form=None, tz=None): | ||
""" Set the x axis as a time formatted axis. | ||
|
||
Parameters | ||
---------- | ||
ax : Matplotlib axis instance | ||
Axis to plot. None will use the current axis. | ||
date_time_form : str | ||
Format of the time string for x-axis labels. | ||
tz : str | ||
Time zone info to use when creating axis labels (see datetime). | ||
""" | ||
if date_time_form is None: | ||
date_time_form = '%H:%M' | ||
|
||
# Set the date format | ||
date_Fmt = DateFormatter(date_time_form, tz=tz) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this used anywhere? |
||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not seeing any minor ticks in my plot, might have something incorrect but it would be good to tests this. I'm also not apposed to not adding minor ticks and leaving this customization to the users. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This might be too much customization to include. I'll remove it. |
||
# Turn the tick marks outward | ||
ax.tick_params(which='both', direction='out') | ||
|
||
########################## | ||
# name generator methods # | ||
########################## | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,30 +1,59 @@ | ||
""" Functions for converting date and time between various forms """ | ||
|
||
from netCDF4 import num2date | ||
from netCDF4 import num2date, date2num | ||
|
||
EPOCH_UNITS = "seconds since 1970-01-01T00:00:00Z" | ||
|
||
def datetime_from_radar(radar): | ||
|
||
def datetime_from_radar(radar, epoch=False): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There needs to be two blank lines before this function to meet PEP8 conventions. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Didn't know that. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The pep8 tool is really helpful to find these. I tend to run in on all Python files I work on before checking the files into git. |
||
""" Return a datetime for the first ray in a Radar. """ | ||
return num2date(radar.time['data'][0], radar.time['units']) | ||
if epoch: | ||
dtrad = num2date(radar.time['data'][0], radar.time['units']) | ||
epnum = date2num(dtrad, EPOCH_UNITS) | ||
return num2date(epnum, EPOCH_UNITS) | ||
else: | ||
return num2date(radar.time['data'][0], radar.time['units']) | ||
|
||
|
||
def datetimes_from_radar(radar): | ||
def datetimes_from_radar(radar, epoch=False): | ||
""" Return an array of datetimes for the rays in a Radar. """ | ||
return num2date(radar.time['data'][:], radar.time['units']) | ||
if epoch: | ||
dtrad = num2date(radar.time['data'][:], radar.time['units']) | ||
epnum = date2num(dtrad, EPOCH_UNITS) | ||
return num2date(epnum, EPOCH_UNITS) | ||
else: | ||
return num2date(radar.time['data'][:], radar.time['units']) | ||
|
||
|
||
def datetime_from_dataset(dataset): | ||
def datetime_from_dataset(dataset, epoch=False): | ||
""" Return a datetime for the first time in a netCDF Dataset. """ | ||
return num2date(dataset.variables['time'][0], | ||
dataset.variables['time'].units) | ||
if epoch: | ||
dtdata = num2date(dataset.variables['time'][0], | ||
dataset.variables['time'].units) | ||
epnum = date2num(dtdata, EPOCH_UNITS) | ||
return num2date(epnum, EPOCH_UNITS) | ||
else: | ||
return num2date(dataset.variables['time'][0], | ||
dataset.variables['time'].units) | ||
|
||
|
||
def datetimes_from_dataset(dataset): | ||
def datetimes_from_dataset(dataset, epoch=False): | ||
""" Return an array of datetimes for the times in a netCDF Dataset. """ | ||
return num2date(dataset.variables['time'][:], | ||
dataset.variables['time'].units) | ||
if epoch: | ||
dtdata = num2date(dataset.variables['time'][:], | ||
dataset.variables['time'].units) | ||
epnum = date2num(dtdata, EPOCH_UNITS) | ||
return num2date(epnum, EPOCH_UNITS) | ||
else: | ||
return num2date(dataset.variables['time'][:], | ||
dataset.variables['time'].units) | ||
|
||
|
||
def datetime_from_grid(grid): | ||
def datetime_from_grid(grid, epoch=False): | ||
""" Return a datetime for the volume start in a Grid. """ | ||
return num2date(grid.time['data'][0], grid.time['units']) | ||
if epoch: | ||
dtrad = num2date(grid.time['data'][0], grid.time['units']) | ||
epnum = date2num(dtrad, EPOCH_UNITS) | ||
return num2date(epnum, EPOCH_UNITS) | ||
else: | ||
return num2date(grid.time['data'][0], grid.time['units']) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The 'test_radardisplay_user_specified_labels' test in test_radar_display.py assumes this method takes 3 parameters. It should be updates with the new call signature (add False before the ax parameter).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done