Skip to content

Commit 64cca36

Browse files
committed
docs: Added query_gns, query_gcmt to docs index. Fixed catalog filtering tutorial links and expanded with m_vs_t plot. Added reference links to multiple tutorials. Changed sphinx confx to not display full function signature in API docs. Added comparative tests/plots to gridded_forecast_+tutorial
refac: shifted some function args ordering ft: Comparative plots now handle being passed only one forecast.
1 parent e693c93 commit 64cca36

11 files changed

+125
-38
lines changed

csep/core/catalogs.py

+23-6
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
from csep.utils.log import LoggingMixin
2424
from csep.utils.readers import csep_ascii
2525
from csep.utils.file import get_file_extension
26-
from csep.utils.plots import plot_catalog
26+
from csep.utils.plots import plot_catalog, plot_magnitude_versus_time
2727

2828

2929
class AbstractBaseCatalog(LoggingMixin):
@@ -829,15 +829,16 @@ def b_positive(self):
829829
""" Implements the b-positive indicator from Nicholas van der Elst """
830830
pass
831831

832-
def plot(self, ax=None, show=False, extent=None, set_global=False, plot_args=None,
833-
**kwargs):
834-
""" Plot catalog according to plate-carree projection
832+
def plot(self, ax=None, show=False, extent=None, set_global=False, **kwargs):
833+
""" Plot catalog according to plate-carree projection. See
834+
https://docs.cseptesting.org/reference/generated/csep.utils.plots.plot_catalog.html for
835+
a description of keyword arguments.
835836
836837
Args:
837838
ax (`matplotlib.pyplot.axes`): Previous axes onto which catalog can be drawn
838839
show (bool): if true, show the figure. this call is blocking.
839840
extent (list): Force an extent [lon_min, lon_max, lat_min, lat_max]
840-
plot_args (optional/dict): dictionary containing plotting arguments for making figures
841+
set_global (bool): Whether to plot using a global projection
841842
842843
Returns:
843844
axes: matplotlib.Axes.axes
@@ -856,14 +857,30 @@ def plot(self, ax=None, show=False, extent=None, set_global=False, plot_args=Non
856857
except AttributeError:
857858
pass
858859

859-
plot_args = plot_args or {}
860+
plot_args = kwargs.get('plot_args', {})
860861
plot_args_default.update(plot_args)
861862

862863
# this call requires internet connection and basemap
863864
ax = plot_catalog(self, ax=ax, show=show, extent=extent,
864865
set_global=set_global, **plot_args_default, **kwargs)
865866
return ax
866867

868+
def plot_magnitude_versus_time(self, ax=None, show=False, **kwargs):
869+
""" Plot the magnitude-time series of a catalog. See
870+
https://docs.cseptesting.org/reference/generated/csep.utils.plots.plot_magnitude_versus_time.html for
871+
a description of keyword arguments.
872+
873+
Args:
874+
ax (`matplotlib.pyplot.axes`): Previous axes onto which catalog can be drawn
875+
show (bool): if true, show the figure. this call is blocking.
876+
877+
Returns:
878+
axes: matplotlib.Axes.axes
879+
"""
880+
881+
ax = plot_magnitude_versus_time(self, ax=ax, show=show, **kwargs)
882+
883+
return ax
867884

868885
class CSEPCatalog(AbstractBaseCatalog):
869886
"""

csep/utils/plots.py

+24-13
Original file line numberDiff line numberDiff line change
@@ -828,9 +828,7 @@ def plot_gridded_dataset(
828828
gridded: numpy.ndarray,
829829
region: "CartesianGrid2D",
830830
basemap: Optional[str] = None,
831-
ax: Optional[pyplot.Axes] = None,
832831
projection: Optional[Union[ccrs.Projection, str]] = None,
833-
show: bool = False,
834832
extent: Optional[List[float]] = None,
835833
set_global: bool = False,
836834
plot_region: bool = True,
@@ -840,6 +838,8 @@ def plot_gridded_dataset(
840838
clabel: Optional[str] = None,
841839
alpha: Optional[float] = None,
842840
alpha_exp: float = 0,
841+
ax: Optional[pyplot.Axes] = None,
842+
show: bool = False,
843843
**kwargs,
844844
) -> matplotlib.axes.Axes:
845845
"""
@@ -856,11 +856,9 @@ def plot_gridded_dataset(
856856
(whose indices correspond to each spatial cell) to a 2D-square array.
857857
region (CartesianGrid2D): Region in which gridded values are contained.
858858
basemap (str): Passed to :func:`~csep.utils.plots.plot_basemap` along with `kwargs`.
859-
ax (matplotlib.axes.Axes): Previously defined ax object. Defaults to `None`.
860859
projection (cartopy.crs.Projection or str): Projection to be used in the underlying
861860
basemap. It can be a cartopy projection instance, or `approx` for a quick
862861
approximation of Mercator. Defaults to :class:`~cartopy.crs.PlateCarree` if `None`.
863-
show (bool): If `True`, displays the plot. Defaults to `False`.
864862
extent (list of float): ``[lon_min, lon_max, lat_min, lat_max]``. Defaults to `None`.
865863
set_global (bool): Display the complete globe as basemap. Defaults to `False`.
866864
plot_region (bool): If `True`, plot the dataset region border. Defaults to `True`.
@@ -871,6 +869,8 @@ def plot_gridded_dataset(
871869
alpha (float): Transparency level. Defaults to `None`.
872870
alpha_exp (float): Exponent for the alpha function (recommended between `0.4` and `1`).
873871
Defaults to `0`.
872+
ax (matplotlib.axes.Axes): Previously defined ax object. Defaults to `None`.
873+
show (bool): If `True`, displays the plot. Defaults to `False`.
874874
**kwargs: Additional keyword arguments to customize the plot:
875875
876876
- **colorbar_labelsize** (`int`): Font size for the colorbar label.
@@ -953,11 +953,11 @@ def plot_test_distribution(
953953
evaluation_result: "EvaluationResult",
954954
bins: Union[str, int, List[Any]] = "fd",
955955
percentile: Optional[int] = 95,
956-
ax: Optional[matplotlib.axes.Axes] = None,
957956
auto_annotate: Union[bool, dict] = True,
958957
sim_label: str = "Simulated",
959958
obs_label: str = "Observation",
960959
legend: bool = True,
960+
ax: Optional[matplotlib.axes.Axes] = None,
961961
show: bool = False,
962962
**kwargs,
963963
) -> matplotlib.axes.Axes:
@@ -1096,8 +1096,8 @@ def plot_test_distribution(
10961096
def plot_calibration_test(
10971097
evaluation_result: "EvaluationResult",
10981098
percentile: float = 95,
1099-
ax: Optional[matplotlib.axes.Axes] = None,
11001099
label: Optional[str] = None,
1100+
ax: Optional[matplotlib.axes.Axes] = None,
11011101
show: bool = False,
11021102
**kwargs,
11031103
) -> matplotlib.axes.Axes:
@@ -1261,6 +1261,13 @@ def _plot_comparison_test(
12611261
plot_args = {**DEFAULT_PLOT_ARGS, **kwargs.get("plot_args", {}), **kwargs}
12621262
fig, ax = pyplot.subplots(figsize=plot_args["figsize"]) if ax is None else (ax.figure, ax)
12631263

1264+
# Handle case when there is only a single pair of t_results and w_results
1265+
if not isinstance(results_t, list):
1266+
results_t = [results_t]
1267+
1268+
if results_w is not None and not isinstance(results_w, list):
1269+
results_w = [results_w]
1270+
12641271
# Iterate through T-test results, or jointly through t- and w- test results
12651272
Results = zip(results_t, results_w) if results_w else zip(results_t)
12661273
for index, result in enumerate(Results):
@@ -1337,11 +1344,15 @@ def _plot_comparison_test(
13371344

13381345
if plot_args["legend"]:
13391346
# Add custom legend to explain results
1347+
13401348
legend_elements = [
13411349
Line2D([0], [0], color="red", lw=2,
13421350
label=f"T-test rejected ($\\alpha = {results_t[0].quantile[-1]}$)"),
13431351
Line2D([0], [0], color="green", lw=2, label="T-test non-rejected"),
1344-
Line2D([0], [0], color="gray", lw=2, label="T-test indistinguishable"),
1352+
Line2D([0], [0], color="gray", lw=2, label="T-test indistinguishable")
1353+
]
1354+
if results_w is not None:
1355+
legend_elements.extend([
13451356
Line2D(
13461357
[0],
13471358
[0],
@@ -1361,8 +1372,8 @@ def _plot_comparison_test(
13611372
markersize=6,
13621373
markerfacecolor="white",
13631374
label="W-test indistinguishable",
1364-
),
1365-
]
1375+
)])
1376+
13661377
ax.legend(handles=legend_elements, loc="best", fontsize=plot_args["legend_fontsize"])
13671378

13681379
if plot_args["tight_layout"]:
@@ -1379,9 +1390,9 @@ def _plot_consistency_test(
13791390
normalize: bool = False,
13801391
one_sided_lower: bool = False,
13811392
percentile: float = 95,
1382-
ax: Optional[pyplot.Axes] = None,
13831393
plot_mean: bool = False,
13841394
color: str = "black",
1395+
ax: Optional[pyplot.Axes] = None,
13851396
show: bool = False,
13861397
**kwargs,
13871398
) -> matplotlib.axes.Axes:
@@ -1523,8 +1534,8 @@ def _plot_concentration_ROC_diagram(
15231534
catalog: "CSEPCatalog",
15241535
linear: bool = True,
15251536
plot_uniform: bool = True,
1526-
show: bool = True,
15271537
ax: Optional[pyplot.Axes] = None,
1538+
show: bool = True,
15281539
**kwargs,
15291540
) -> matplotlib.axes.Axes:
15301541
"""
@@ -1649,8 +1660,8 @@ def _plot_ROC_diagram(
16491660
catalog: "CSEPCatalog",
16501661
linear: bool = True,
16511662
plot_uniform: bool = True,
1652-
show: bool = True,
16531663
ax: Optional[pyplot.Axes] = None,
1664+
show: bool = True,
16541665
**kwargs,
16551666
) -> matplotlib.pyplot.Axes:
16561667
"""
@@ -1786,8 +1797,8 @@ def _plot_Molchan_diagram(
17861797
catalog: "CSEPCatalog",
17871798
linear: bool = True,
17881799
plot_uniform: bool = True,
1789-
show: bool = True,
17901800
ax: Optional[pyplot.Axes] = None,
1801+
show: bool = True,
17911802
**kwargs,
17921803
) -> matplotlib.axes.Axes:
17931804

docs/concepts/regions.rst

+12-2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
Regions
55
#######
66

7+
.. automodule:: csep.core.regions
78
.. automodule:: csep.utils.basic_types
89

910
PyCSEP includes commonly used CSEP testing regions and classes that facilitate working with gridded data sets. This
@@ -15,7 +16,6 @@ module is early in development and will be a focus of future development.
1516

1617
.. :currentmodule:: csep
1718
18-
.. automodule:: csep.core.regions
1919
2020
Practically speaking, earthquake forecasts, especially time-dependent forecasts, treat time differently than space and
2121
magnitude. If we consider a family of monthly forecasts for the state of California for earthquakes with **M** 3.95+,
@@ -98,7 +98,8 @@ mapping defined in (2). The :meth:`get_index_of<csep.core.regions.CartesianGrid2
9898
of longitudes and latitudes and returns the index of the polygon they are associated with. For instance, this index can
9999
now be used to access a data value stored in another data structure.
100100

101-
.. ***************
101+
.. _testing-regions:
102+
102103
Testing Regions
103104
########################
104105

@@ -110,8 +111,17 @@ these regions.
110111

111112
california_relm_region
112113
italy_csep_region
114+
nz_csep_region
113115
global_region
114116

117+
Also, the CSEP collection regions (i.e., extended regions where data were collected to create forecasts in testing regions) can be obtained as:
118+
119+
.. autosummary::
120+
121+
california_relm_collection_region
122+
italy_csep_collection_region
123+
nz_csep_collection_region
124+
115125
.. ****************
116126
Region Utilities
117127
########################

docs/conf.py

+1
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,7 @@
176176
# Insert links to documentation of objects in the examples
177177
"reference_url": {"csep": None},
178178
}
179+
autodoc_typehints = "description"
179180

180181
# -- Options for HTMLHelp output ---------------------------------------------
181182

docs/getting_started/theory.rst

+2
Original file line numberDiff line numberDiff line change
@@ -551,6 +551,8 @@ likelihood falls in the tail of the simulated likelihood distribution.
551551
Again this is shown by a coloured symbol which highlights whether the
552552
forecast model passes or fails the test.
553553

554+
.. _forecast-comparison-tests:
555+
554556
Forecast comparison tests
555557
~~~~~~~~~~~~~~~~~~~~~~~~~
556558

docs/reference/api_reference.rst

+3-1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ Loading catalogs and forecasts
1717
load_catalog
1818
query_comcat
1919
query_bsi
20+
query_gns
21+
query_gcmt
2022
load_gridded_forecast
2123
load_catalog_forecast
2224

@@ -249,7 +251,7 @@ Plotting catalog-based evaluations:
249251
.. autosummary::
250252
:toctree: generated
251253

252-
plot_distribution_test
254+
plot_test_distribution
253255
plot_calibration_test
254256

255257
Plotting grid-based evaluations:

examples/tutorials/catalog_filtering.py

+25-6
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,19 @@
2424
import csep
2525
from csep.core import regions
2626
from csep.utils import time_utils, comcat
27-
# sphinx_gallery_thumbnail_path = '_static/CSEP2_Logo_CMYK.png'
2827

2928
####################################################################################################################################
3029
# Load catalog
3130
# ------------
3231
#
33-
# PyCSEP provides access to the ComCat web API using :func:`csep.query_comcat` and to the Bollettino Sismico Italiano
34-
# API using :func:`csep.query_bsi`. These functions require a :class:`datetime.datetime` to specify the start and end
35-
# dates.
32+
# PyCSEP provides access to multiple catalog webservices, using the following functions:
33+
#
34+
# * `ANSS Comprehensive Earthquake Catalog (ComCat) <https://earthquake.usgs.gov/data/comcat/>`_: :func:`csep.query_comcat`
35+
# * `INGV Bolletino Sismico Italiano (BSI) <https://terremoti.ingv.it/en/bsi>`_: :func:`csep.query_bsi`
36+
# * `GNS New Zealand GeoNet <https://www.geonet.org.nz/>`_: :func:`csep.query_gns`
37+
# * `Global CMT <https://www.globalcmt.org/>`_ (through the `ISC <https://www.isc.ac.uk/>`_ API): :func:`csep.query_gcmt`
38+
#
39+
# These functions require a :class:`datetime.datetime` to specify the start and end dates of the query.
3640

3741
start_time = csep.utils.time_utils.strptime_to_utc_datetime('2019-01-01 00:00:00.0')
3842
end_time = csep.utils.time_utils.utc_now_datetime()
@@ -91,18 +95,33 @@
9195
catalog = catalog.filter_spatial(aftershock_region).apply_mct(event.magnitude, m71_epoch)
9296
print(catalog)
9397

98+
####################################################################################################################################
99+
# Additional CSEP regions (e.g., California, Italy, New Zealand) can be accessed through the :mod:`csep.core.regions` module. See :ref:`testing-regions` for more information.
100+
94101

95102
####################################################################################################################################
96103
# Plot catalog
97104
# -------------
98105
#
99-
# To visualize the catalog, use :meth:`csep.core.catalogs.AbstractBaseCatalog.plot` to plot it spatially
106+
# To visualize the catalog spatially, simply use the method :meth:`~csep.core.catalogs.CSEPCatalog.plot`
100107
catalog.plot(show=True)
101108

102109

110+
####################################################################################################################################
111+
# To plot the magnitude time series, use :meth:`~csep.core.catalogs.CSEPCatalog.plot_magnitude_vs_time`
112+
catalog.plot_magnitude_versus_time(show=True)
113+
103114
####################################################################################################################################
104115
# Write catalog
105116
# -------------
106117
#
107-
# Use :meth:`csep.core.catalogs.AbstractBaseCatalog.write_ascii` to write the catalog into the comma separated value format.
118+
# Use the method :meth:`~csep.core.catalogs.CSEPCatalog.write_ascii` to write the catalog into the comma separated value format.
108119
catalog.write_ascii('2019-11-11-comcat.csv')
120+
121+
122+
####################################################################################################################################
123+
# Load catalog
124+
# ------------
125+
#
126+
# Also, the function :func:`csep.load_catalog` can be used to read catalogs un multiple formats (See :ref:`catalogs-reference`)
127+
catalog = csep.load_catalog('2019-11-11-comcat.csv')

0 commit comments

Comments
 (0)