Skip to content

Commit

Permalink
Moved KPP-Standalone plotting code to gcpy/kpp folder
Browse files Browse the repository at this point in the history
gcpy/examples/__init__.py
- Removed "from ,kpp import*"

gcpy/kpp/__init__.py
- Added this import script for the gcpy/kpp folder

gcpy/kpp/kppsa_utils.py
- Moved most of the routines from the former
  gcpy/examples/kpp/kppsa_visualize.py script here
  so that they can be reused

gcpy/kpp/kppsa_plot_sites.py
- Added this script to plot KPP-Standalone box model output
  (Ref vs. Dev versions) from 500-1000 hPa.  Based on the former
  kppsa_visualize.py script.

gcpy/kpp/kppsa_quick_look.py
- Added this script to create "quick-look" output from the
  KPP-Standalone box model output

CHANGELOG.md
- Updated accordingly

Signed-off-by: Bob Yantosca <[email protected]>
  • Loading branch information
yantosca committed Dec 11, 2024
1 parent 598514c commit 9823781
Show file tree
Hide file tree
Showing 7 changed files with 744 additions and 2 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
- Added module `benchmark_gcclassic_stats.py` for scraping statistics from GEOS-Chem Classic cloud benchmarks
- Added dry deposition velocity comparison plots in 1-month cloud benchmarks
- Added `gcpy/benchmark/modules/benchmark_species_changes.py` to compute the table of species changes between versions
- Added `gcpy/examples/kpp/kppsa_visualize.py` script to plot output from the KPP-Standalone box model
- Added `gcpy/kpp/` folder containing scripts to plot output from the KPP-Standalone box model

### Changed
- Changed format of `% diff` column from `12.3e` to `12.3f` in benchmark timing tables
Expand Down
1 change: 0 additions & 1 deletion gcpy/examples/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
#from .bpch_to_nc import *
from .diagnostics import *
from .dry_run import *
from .kpp import *
from .plotting import *
from .timeseries import *
from .working_with_files import *
Expand Down
6 changes: 6 additions & 0 deletions gcpy/kpp/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
"""
GCPy import script
"""
from .kppsa_utils import *
from .kppsa_quick_look import *
from .kppsa_plot_sites import *
168 changes: 168 additions & 0 deletions gcpy/kpp/kppsa_plot_sites.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
#!/usr/bin/env python3
"""
Script to visualize output from the KPP standalone box model.
"""

# Imports
import argparse
from matplotlib.backends.backend_pdf import PdfPages
import matplotlib.pyplot as plt
from gcpy.util import verify_variable_type
from gcpy.kpp.kppsa_utils import \
kppsa_get_file_list, kppsa_get_unique_site_names,\
kppsa_plot_one_page, kppsa_read_csv_files


def kppsa_plot_species_at_sites(
ref_file_list,
ref_label,
dev_file_list,
dev_label,
species,
pdfname,
):
"""
TBD
"""
verify_variable_type(ref_file_list, list)
verify_variable_type(ref_label, str)
verify_variable_type(dev_file_list, list)
verify_variable_type(dev_label, str)
verify_variable_type(species, str)
verify_variable_type(pdfname, str)

# Read data
ref_data = kppsa_read_csv_files(ref_file_list)
dev_data = kppsa_read_csv_files(dev_file_list)

# Get a list of site names sorted from N to S
site_names = kppsa_get_unique_site_names(ref_data)

# Figure setup
plt.style.use("seaborn-v0_8-darkgrid")
rows_per_page = 3
cols_per_page = 2
plots_per_page = rows_per_page * cols_per_page

# Open the plot as a PDF document
if ".pdf" not in pdfname:
pdfname += ".pdf"
pdf = PdfPages(f"{pdfname}")

# Loop over the number of obs sites that fit on a page
for start in range(0, len(site_names), plots_per_page):
end = start + plots_per_page - 1
kppsa_plot_one_page(
pdf,
site_names[start:end+1],
ref_data,
ref_label,
dev_data,
dev_label,
species,
rows_per_page,
cols_per_page,
font_scale=1.0,
)

# Close the PDF file
pdf.close()

# Reset the plot style (this prevents the seaborn style from
# being applied to other model vs. obs plotting scripts)
plt.style.use("default")


def main():
"""
TBD
"""
# Tell the parser which arguments to look for
parser = argparse.ArgumentParser(
description="Single-panel plotting example program"
)
parser.add_argument(
"--refdir",
metavar="REFDIR",
type=str,
required=True,
help="Directory w/ KPP-Standalone log files (Ref version)"
)
parser.add_argument(
"--reflabel",
metavar="REFLABEL",
type=str,
required=False,
help="Descriptive label for the Ref data",
default="Ref"
)
parser.add_argument(
"--devdir",
metavar="DEVDIR",
type=str,
required=True,
help="Directory w/ KPP-Standalone log files (Dev version)"
)
parser.add_argument(
"--devlabel",
metavar="DEVLABEL",
type=str,
required=False,
help="Descriptive label for the Ref data",
default="Dev"
)
parser.add_argument(
"--pattern",
metavar="PATTERN",
type=str,
required=False,
help="Search for file names matching this pattern",
)
parser.add_argument(
"--species",
metavar="SPECIES",
type=str,
required=True,
help="Species to plot"
)
parser.add_argument(
"--pdfname",
metavar="PDF-FILE-NAME",
type=str,
required=False,
help="Name of the PDF file to be created",
default="kppsa_output.pdf"
)

# Parse command-line arguments
args = parser.parse_args()

# Get a list of KPP-Standalone files matching the criteria (Ref)
ref_file_list = kppsa_get_file_list(
args.refdir,
args.pattern,
)
if len(ref_file_list) == 0:
msg = "Could not find any files matching {pattern} for Ref!"
raise ValueError(msg)

dev_file_list = kppsa_get_file_list(
args.devdir,
args.pattern,
)
if len(ref_file_list) == 0:
msg = "Could not find any files matching {pattern} for Dev!"
raise ValueError(msg)

# Plot data
kppsa_plot_species_at_sites(
ref_file_list,
args.reflabel,
dev_file_list,
args.devlabel,
args.species,
args.pdfname,
)

if __name__ == '__main__':
main()
144 changes: 144 additions & 0 deletions gcpy/kpp/kppsa_quick_look.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
#!/usr/bin/env python3
"""
Creates a "quick-look" plot from KPP-Standalone box model output.
"""

# Imports
import argparse
import matplotlib.pyplot as plt
from gcpy.util import verify_variable_type
from gcpy.kpp.kppsa_utils import \
kppsa_get_file_list, kppsa_get_unique_site_names, \
kppsa_plot_single_site, kppsa_prepare_site_data, \
kppsa_read_csv_files


def kppsa_make_quick_look_plot(file_list, label, species):
"""
Creates a quick-look plot from KPP-Standalone box model output.
Args
file_list : list : List of KPP-Standalone log files
site_name : str : Name of the site that you wish to plot
label : str : Descriptive label for the data
species : str : Name of the species that you wish to plot
"""
verify_variable_type(file_list, list)
verify_variable_type(label, str)
verify_variable_type(species, str)

# Read data
dframe = kppsa_read_csv_files(file_list)

# Get the site name from the DataFrame
site_name = kppsa_get_unique_site_names(dframe)[0]

# Get the data for the given species and site
site_data, site_title = kppsa_prepare_site_data(
dframe,
site_name,
species,
)

# Figure setup
plt.style.use("seaborn-v0_8-darkgrid")

# Define a new matplotlib.figure.Figure object for this page
# Landscape width: 11" x 8"
fig = plt.figure(figsize=(11, 8))
fig.tight_layout()

# Figure setup
plt.style.use("seaborn-v0_8-darkgrid")

# Plot species vertical profile at a given site
kppsa_plot_single_site(
fig,
rows_per_page=1,
cols_per_page=1,
subplot_index=0,
subplot_title=site_title,
ref_data=site_data,
ref_label=label,
dev_data=None,
dev_label=None,
species=species,
font_scale=2.0,
)

# Add top-of-page legend
plt.legend(
ncol=3,
bbox_to_anchor=(0.5, 0.98),
bbox_transform=fig.transFigure,
loc='upper center'
)

# Show the plot
plt.show()

# Reset the plot style (this prevents the seaborn style from
# being applied to other model vs. obs plotting scripts)
plt.style.use("default")


def main():
"""
Parses arguments and calls function kppsa_make_quick_look_plot
to generate a "quick-look" plot from KPP-Standalone box model
output.
"""

# Tell the parser which arguments to look for
parser = argparse.ArgumentParser(
description="Single-panel plotting example program"
)
parser.add_argument(
"-d", "--dirname",
metavar="DIRNAME",
type=str,
required=True,
help="Directory containing KPP-Standalone output files"
)
parser.add_argument(
"-l", "--label",
metavar="LABEL",
type=str,
required=False,
help="Descriptive label",
default="KPP-Standalone output"
)
parser.add_argument(
"-p", "--pattern",
metavar="PATTERN",
type=str,
required=False,
help="Search for file names matching this pattern",
)
parser.add_argument(
"-s", "--species",
metavar="SPECIES",
type=str,
required=True,
help="Species to plot"
)

# Parse command-line arguments
args = parser.parse_args()

# Get a list of KPP-Standalone files matching the criteria
file_list = kppsa_get_file_list(
args.dirname,
args.pattern,
)

# Create the quick look plot from KPP-Standalone output
kppsa_make_quick_look_plot(
file_list,
args.label,
args.species
)


if __name__ == '__main__':
main()
Loading

0 comments on commit 9823781

Please sign in to comment.