Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
A
AossTower
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Deploy
Model registry
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
MetObs
AossTower
Commits
25fe631d
Unverified
Commit
25fe631d
authored
7 years ago
by
David Hoese
Browse files
Options
Downloads
Patches
Plain Diff
Add units to meteorogram plots
parent
730ee1ab
No related branches found
No related tags found
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
aosstower/tower_quicklooks/create_quicklook.py
+18
-294
18 additions, 294 deletions
aosstower/tower_quicklooks/create_quicklook.py
with
18 additions
and
294 deletions
aosstower/tower_quicklooks/create_quicklook.py
+
18
−
294
View file @
25fe631d
...
...
@@ -28,6 +28,10 @@ def remove_yticklines(ax):
t
.
set_visible
(
False
)
def
get_subtitle_location
(
num_subplots
):
return
1
-
0.055
*
num_subplots
class
PlotMaker
(
object
):
"""
Object for making plots and storing/validating plot metadata
"""
def
__init__
(
self
,
name
,
dependencies
,
title
=
None
,
units
=
None
):
...
...
@@ -86,8 +90,13 @@ class PlotMaker(object):
if
y_label
and
not
is_subplot
:
ax
.
set_ylabel
(
y_label
)
if
is_subplot
:
# put units on the top left of the plot axes
ax
.
text
(.
008
,
.
9
,
self
.
units
,
horizontalalignment
=
'
left
'
,
va
=
'
top
'
,
transform
=
ax
.
transAxes
,
size
=
8
)
def
_call_plot
(
self
,
frame
,
ax
):
print
(
self
.
name
,
frame
.
columns
)
lines
=
ax
.
plot
(
frame
.
index
,
frame
,
'
k
'
)
return
lines
...
...
@@ -190,6 +199,9 @@ class PlotMaker(object):
ax
.
spines
[
'
top
'
].
set_visible
(
False
)
ax
.
spines
[
'
bottom
'
].
set_visible
(
False
)
for
t
in
ax
.
texts
:
t
.
set_visible
(
False
)
def
convert_to_thumbnail
(
self
,
fig
,
fig_size
=
TN_SIZE
):
fig
=
self
.
_convert_fig_to_thumbnail
(
fig
,
fig_size
)
self
.
_convert_ax_to_thumbnail
(
fig
)
...
...
@@ -345,7 +357,7 @@ PLOT_TYPES = {
'
wind_dir
'
:
WindDirPlotMaker
(
'
wind_dir
'
,
(
'
wind_dir
'
,),
units
=
'
°
'
),
# special tick labels
'
rh
'
:
PlotMaker
(
'
rh
'
,
(
'
rh
'
,),
units
=
'
%
'
),
'
air_temp
'
:
PlotMaker
(
'
air_temp
'
,
(
'
air_temp
'
,),
units
=
'
°C
'
),
'
pressure
'
:
PlotMaker
(
'
pressure
'
,
(
'
pressure
'
,),
units
=
'
h
p
a
'
),
'
pressure
'
:
PlotMaker
(
'
pressure
'
,
(
'
pressure
'
,),
units
=
'
h
P
a
'
),
'
dewpoint
'
:
PlotMaker
(
'
dewpoint
'
,
(
'
air_temp
'
,),
units
=
'
°C
'
),
'
wind_speed
'
:
PlotMaker
(
'
wind_speed
'
,
(
'
wind_speed
'
,),
units
=
'
m/s
'
),
'
accum_precip
'
:
PrecipPlotMaker
(
'
accum_precip
'
,
(
'
accum_precip
'
,),
units
=
'
mm
'
),
...
...
@@ -377,255 +389,8 @@ def get_data(input_files, columns):
return
pd
.
DataFrame
(
data_dict
).
set_index
([
'
stamps
'
])
# The purpose of this method is to determines all the 12:00:00 days
# within a start and end date
# @param cur_dt - start time
# @param dates - end time
# @return dates in lists
def
get_dates_in_range
(
cur_dt
,
end
):
curr
=
cur_dt
while
curr
<=
end
:
yield
curr
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
# in that array
# @param dewpoint stamps - time stamps for valid dewpoint data. Only specified if
# air temp and dew point need to be ploted in the same plot
# @param dates - time stamps for data
# @return datesInRange - all days with 12:00:00
def
find_half_days
(
dewpoint_stamps
,
dates
):
date_max
=
np
.
amax
(
dates
)
date_min
=
np
.
amin
(
dates
)
if
(
dewpoint_stamps
):
dew_max
=
np
.
amax
(
dewpoint_stamps
)
dew_min
=
np
.
amin
(
dewpoint_stamps
)
date_max
=
max
(
date_max
,
dew_max
)
date_min
=
min
(
date_min
,
dew_min
)
cur_dt
=
date_min
.
replace
(
hour
=
12
,
minute
=
0
,
second
=
0
)
if
cur_dt
<
date_min
:
cur_dt
+=
timedelta
(
days
=
1
)
datesInRange
=
list
(
get_dates_in_range
(
cur_dt
,
date_max
))
return
datesInRange
# The purpose of this method is to create a thumbnail plot
# @param frame - all data I need in a data frame
# @param ymin - lower limit of the y axis if specified. set only when --daily is given
# @param ymax - upper limit of yaxis if specified. Set only when --daily is given
# @param dewpoint_stamps - timestamps for valid dewpoint data. Only specified if
# air temp and dew point need to be plotted in the same plot
# @param dewpoint_data - valid dewpoint data. Only specified if
# air temp and dew point need to be plotted in the same plot
#@param output - output filename pattern
def
thumbnail_plot
(
dates
,
data
,
ymin
,
ymax
,
dewpoint_stamps
,
dewpoint_data
,
output
,
wind_dir
):
if
(
dewpoint_stamps
):
plt
.
plot
(
dates
,
data
,
'
r
'
,
dewpoint_stamps
,
dewpoint_data
,
'
b
'
)
plt
.
axis
([
min
(
dates
),
max
(
dates
),
ymin
,
ymax
])
#plt.plot(dewpoint_stamps, dewpoint_data, 'b')
elif
(
wind_dir
):
plt
.
plot
(
dates
,
data
,
'
ko
'
,
markersize
=
0.1
)
plt
.
axis
([
min
(
dates
),
max
(
dates
),
0
,
360
])
else
:
plt
.
plot
(
dates
,
data
,
'
k
'
)
plt
.
axis
([
min
(
dates
),
max
(
dates
),
ymin
,
ymax
])
#scale
fig
=
plt
.
gcf
()
dpi
=
fig
.
get_dpi
()
fig
.
set_size_inches
(
80
/
float
(
dpi
),
80
/
float
(
dpi
))
#create axes
axes
=
plt
.
gca
()
axes
.
axes
.
get_xaxis
().
set_ticklabels
([])
axes
.
axes
.
get_xaxis
().
set_tick_params
(
length
=
7
)
axes
.
axes
.
get_yaxis
().
set_ticklabels
([])
axes
.
axes
.
get_yaxis
().
set_visible
(
False
)
axes
.
spines
[
'
right
'
].
set_visible
(
False
)
axes
.
spines
[
'
bottom
'
].
set_visible
(
False
)
#got the basic shape of the plot
#still need to draw a line in the middle
datesInRange
=
find_half_days
(
dewpoint_stamps
,
dates
)
for
date
in
datesInRange
:
plt
.
axvline
(
x
=
date
,
color
=
'
k
'
)
# The purpose of this method is to create a thumbnail
# @param frame - all data I need in a data frame
# @param ymin - lower limit of the y axis if specified. set only when --daily is given
# @param ymax - upper limit of yaxis if specified. Set only when --daily is given
# @param create_air_dew_plot - boolean specifying if air temp and dewpoint
# @param output - output filename pattern
# should be in same plot
def
create_thumbnail
(
plot_names
,
frame
,
ymin
,
ymax
,
create_air_dew_plot
,
output
):
#see if we're going to need subplots
#subplots needed when len is greater than 2 for one variable
#or greater than 4 for two variables
need_subplots
=
len
(
list
(
frame
.
columns
.
values
))
>
2
and
not
create_air_dew_plot
need_subplots
=
need_subplots
or
len
(
list
(
frame
.
columns
.
values
))
>
4
and
create_air_dew_plot
if
need_subplots
:
plots_created
=
1
if
create_air_dew_plot
:
numberPlots
=
(
len
(
list
(
frame
.
columns
.
values
))
-
2
)
/
2
plotNumber
=
numberPlots
*
100
+
10
else
:
numberPlots
=
len
(
list
(
frame
.
columns
.
values
))
/
2
plotNumber
=
numberPlots
*
100
+
10
stamps
=
frame
.
index
#get dewpoint data
if
create_air_dew_plot
:
all_data
=
frame
[
'
dewpoint
'
]
qc_data
=
frame
[
'
qc_dewpoint
'
]
good_list
=
get_good_data
(
qc_data
,
stamps
,
all_data
)
dewpoint_data
=
good_list
[
0
]
dewpoint_stamps
=
good_list
[
1
]
for
name
in
plot_names
:
if
name
==
'
dewpoint
'
and
create_air_dew_plot
:
continue
if
name
not
in
list
(
frame
.
columns
.
values
):
continue
elif
need_subplots
:
plt
.
subplot
(
plotNumber
+
plots_created
)
plots_created
+=
1
all_data
=
frame
[
name
]
qc_data
=
frame
[
'
qc_
'
+
name
]
good_list
=
get_good_data
(
qc_data
,
stamps
,
all_data
)
good_data
=
good_list
[
0
]
good_stamps
=
good_list
[
1
]
#if we don't need two lines in same plot, plot
if
not
(
create_air_dew_plot
and
name
==
'
air_temp
'
):
if
name
!=
'
wind_dir
'
:
thumbnail_plot
(
good_stamps
,
good_data
,
ymin
[
name
],
ymax
[
name
],
None
,
None
,
output
,
False
)
if
name
==
'
wind_dir
'
:
thumbnail_plot
(
good_stamps
,
good_data
,
ymin
[
name
],
ymax
[
name
],
None
,
None
,
output
,
True
)
else
:
thumbnail_plot
(
good_stamps
,
good_data
,
ymin
[
name
],
ymax
[
name
],
dewpoint_stamps
,
dewpoint_data
,
output
,
False
)
plt
.
savefig
(
output
.
format
(
plot_name
=
'
test
'
,
start_time
=
good_stamps
[
0
]))
def
full_plot_stamps
(
stamps
):
# assume the timestamps are monotonic
first_stamp
=
stamps
[
0
].
replace
(
hour
=
0
,
minute
=
0
,
second
=
0
)
return
[((
s
-
first_stamp
).
total_seconds
()
/
3600
)
for
s
in
stamps
]
# The purpose of this method is to change how the y ticks are shown
# @param min - minimum of the y range right now
# @param max - maximum of the y range right now
# @return new tick labels
def
get_new_labels
(
mini
,
maxi
):
delta
=
math
.
ceil
((
maxi
-
mini
)
/
6
)
return
np
.
arange
(
mini
,
(
mini
+
delta
*
6
),
delta
)
# The purpose of this method is to create a full_size plot
# @param frame - all data I need in a data frame
# @param ymin - lower limit of the y axis if specified. set only when --daily is given
# @param ymax - upper limit of yaxis if specified. Set only when --daily is given
# @param dewpoint_stamps - timestamps for valid dewpoint data. Only specified if
# air temp and dew point need to be plotted in the same plot
# @param dewpoint_data - valid dewpoint data. Only specified if
# air temp and dew point need to be plotted in the same plot
# @param output - output filename pattern
# @param wind_direction - says different yaxis labels
# @param accum_precip - different yaxis handling
# @param see if we need subplots
def
full_plot
(
fig
,
axes
,
dates
,
data
,
ymin
,
ymax
,
dewpoint_stamps
,
dewpoint_data
,
output
,
wind_dir
,
accum_precip
,
need_subplots
):
dates
=
full_plot_stamps
(
dates
)
if
(
dewpoint_stamps
):
dewpoint_stamps
=
full_plot_stamps
(
dewpoint_stamps
)
plt
.
plot
(
dates
,
data
,
'
r
'
,
dewpoint_stamps
,
dewpoint_data
,
'
b
'
)
plt
.
axis
([
min
(
dates
),
max
(
dates
),
ymin
,
ymax
])
#labels = [math.ceil(float(item.get_text())) for item in ticks]
#plt.plot(dewpoint_stamps, dewpoint_data, 'b')
elif
(
wind_dir
):
plt
.
plot
(
dates
,
data
,
'
ko
'
,
markersize
=
1
)
plt
.
axis
([
min
(
dates
),
max
(
dates
),
0
,
360
])
axes
=
plt
.
gca
()
axes
.
get_yaxis
().
set_ticks
([
0
,
90
,
180
,
270
])
else
:
# import ipdb; ipdb.set_trace()
plt
.
plot
(
dates
,
data
,
'
k
'
)
# plt.axis([min(dates), max(dates), ymin, ymax])
if
not
need_subplots
:
return
#if not wind_direction, reset yaxis ticks
if
not
wind_dir
:
if
not
accum_precip
:
mini
,
maxi
=
axes
.
get_ylim
()
new_labels
=
get_new_labels
(
mini
,
maxi
)
else
:
mini
,
maxi
=
axes
.
get_ylim
()
delta
=
((
maxi
-
mini
)
/
6
)
new_labels
=
np
.
arange
(
mini
,
(
mini
+
delta
*
6
),
delta
)
if
len
(
new_labels
)
==
0
:
new_labels
=
[
0
,
0.05
,
0.1
]
plt
.
yticks
(
new_labels
)
axes
.
get_yaxis
().
get_major_ticks
()[
-
1
].
set_visible
(
False
)
#hid last tick because for subplots above the last one, it's peeping out...
# will show for the last subplot or when subplots are not needed
# in other words, this code should only affect plots above the last plot
# only when sublots are needed
axes
.
get_xaxis
().
get_major_ticks
()[
-
1
].
set_visible
(
False
)
axes
.
get_xaxis
().
get_major_ticks
()[
0
].
set_visible
(
False
)
# The purpose of this method is to get the subtitle's y coordinate
# based upon how many subplots there are
# @param numSubPlots - number of subplots
# @return y-coordinate of subtitle
def
get_subtitle_location
(
numSubPlots
):
return
1
-
0.055
*
numSubPlots
def
create_full_plot
(
plot_names
,
frame
,
output
,
start_time
=
None
,
end_time
=
None
,
thumbnail
=
False
):
def
create_plot
(
plot_names
,
frame
,
output
,
start_time
=
None
,
end_time
=
None
,
thumbnail
=
False
):
"""
Args:
...
...
@@ -672,49 +437,9 @@ def create_full_plot(plot_names, frame, output,
stem
,
ext
=
os
.
path
.
splitext
(
out_fn
)
out_fn
=
"
{}_thumbnail{}
"
.
format
(
stem
,
ext
)
plot_maker
.
convert_to_thumbnail
(
fig
)
LOG
.
info
(
"
Saving thumbnail
'
{}
'
to filename
'
{}
'"
.
format
(
name
,
out_fn
))
fig
.
savefig
(
out_fn
)
# all_data = frame[name]
# qc_data = frame['qc_' + name]
#
# good_list = get_good_data(qc_data, stamps, all_data)
# good_data = good_list[0]
# good_stamps = good_list[1]
#
# dateString = good_stamps[0].strftime('%m/%d/%Y')
#
# # create plots
# if need_subplots:
# if plots_created == 1:
# plt.figure().suptitle('AO&SS Building Tower Meteorogram ' + dateString, fontsize=13)
# ax1 = plt.subplot(plotNumber + plots_created)
# ax1.set_title(TITLES[name], x=0.5, y=get_subtitle_location(numberPlots), fontsize=8)
# else:
# curr_plot = plt.subplot(plotNumber + plots_created, sharex=ax1)
# curr_plot.set_title(TITLES[name], x=0.5, y=get_subtitle_location(numberPlots), fontsize=8)
#
# plots_created += 1
#
# else:
# plt.figure().suptitle('AO&SS Building Tower ' + IND_TITLES[name] + ' ' + dateString, fontsize=13)
# plt.ylabel(TITLES[name])
#
# #if we don't need two lines in same plot, plot
# if not (create_air_dew_plot and name == 'air_temp'):
# full_plot(good_stamps, good_data, ymin[name], ymax[name],
# None, None, output, name == 'wind_dir',
# name == 'accum_precip', need_subplots)
#
# else:
# full_plot(good_stamps, good_data, ymin[name], ymax[name],
# dewpoint_stamps, dewpoint_data, output, False, False,
# need_subplots)
# if need_subplots:
# plt.subplots_adjust(hspace=0, bottom=0.125)
#
# plt.xlabel('Time (UTC)')
def
_dt_convert
(
datetime_str
):
try
:
...
...
@@ -764,7 +489,6 @@ def main():
plot_deps
=
[
PLOT_TYPES
[
k
].
deps
if
k
in
PLOT_TYPES
else
(
k
,)
for
k
in
args
.
plot_names
]
plot_deps
=
list
(
set
(
d
for
deps
in
plot_deps
for
d
in
deps
))
print
(
plot_deps
)
frame
=
get_data
(
args
.
input_files
,
plot_deps
)
bad_plot_names
=
set
(
args
.
plot_names
)
-
(
set
(
frame
.
columns
)
|
set
(
PLOT_TYPES
.
keys
()))
if
bad_plot_names
:
...
...
@@ -793,7 +517,7 @@ def main():
start_time
=
args
.
start_time
end_time
=
args
.
end_time
create_
full_
plot
(
args
.
plot_names
,
frame
,
args
.
output
,
start_time
,
end_time
,
args
.
thumbnail
)
create_plot
(
args
.
plot_names
,
frame
,
args
.
output
,
start_time
,
end_time
,
args
.
thumbnail
)
if
__name__
==
"
__main__
"
:
sys
.
exit
(
main
())
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment