Skip to content

Commit 0eb4dae

Browse files
committed
updated catalog forecast evaluation plots with better plot-args
added plotting functions to api-reference in docs
1 parent 9e53c0a commit 0eb4dae

File tree

2 files changed

+175
-61
lines changed

2 files changed

+175
-61
lines changed

csep/utils/plots.py

Lines changed: 170 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -389,7 +389,7 @@ def plot_histogram(simulated, observation, bins='fd', percentile=None,
389389
pyplot.show()
390390
return ax
391391

392-
def plot_ecdf(x, ecdf, axes=None, xv=None, show=False, plot_args = None):
392+
def plot_ecdf(x, ecdf, axes=None, xv=None, show=False, plot_args=None):
393393
""" Plots empirical cumulative distribution function. """
394394
plot_args = plot_args or {}
395395
# get values from plotting args
@@ -970,32 +970,56 @@ def plot_number_test(evaluation_result, axes=None, show=True, plot_args=None):
970970
Takes result from evaluation and generates a specific histogram plot to show the results of the statistical evaluation
971971
for the n-test.
972972
973-
974973
Args:
975974
evaluation_result: object-like var that implements the interface of the above EvaluationResult
975+
axes (matplotlib.Axes): axes object used to chain this plot
976+
show (bool): if true, call pyplot.show()
977+
plot_args(dict): optional argument containing a dictionary of plotting arguments, with keys as strings and items as described below
978+
979+
Optional plotting arguments:
980+
* figsize: (:class:`list`/:class:`tuple`) - default: [6.4, 4.8]
981+
* title: (:class:`str`) - default: name of the first evaluation result type
982+
* title_fontsize: (:class:`float`) Fontsize of the plot title - default: 10
983+
* xlabel: (:class:`str`) - default: 'X'
984+
* xlabel_fontsize: (:class:`float`) - default: 10
985+
* xticks_fontsize: (:class:`float`) - default: 10
986+
* ylabel_fontsize: (:class:`float`) - default: 10
987+
* text_fontsize: (:class:`float`) - default: 14
988+
* tight_layout: (:class:`bool`) Set matplotlib.figure.tight_layout to remove excess blank space in the plot - default: True
989+
* percentile (:class:`float`) Critial region to shade on histogram - default: 95
990+
* bins: (:class:`str`) - Set binning type. see matplotlib.hist for more info - default: 'auto'
991+
* xy: (:class:`list`/:class:`tuple`) - default: (0.55, 0.3)
976992
977993
Returns:
978994
ax (matplotlib.axes.Axes): can be used to modify the figure
979995
980996
"""
981-
plot_args = plot_args or {}
982-
# handle plotting
997+
998+
# chain plotting axes if requested
983999
if axes:
9841000
chained = True
9851001
else:
9861002
chained = False
987-
# supply fixed arguments to plots
988-
# might want to add other defaults here
989-
filename = plot_args.get('filename', None)
990-
xlabel = plot_args.get('xlabel', 'Event count of catalog')
1003+
1004+
# default plotting arguments
1005+
plot_args = plot_args or {}
1006+
title = plot_args.get('title', 'Number Test')
1007+
title_fontsize = plot_args.get('title_fontsize', None)
1008+
xlabel = plot_args.get('xlabel', 'Event count of catalogs')
1009+
xlabel_fontsize = plot_args.get('xlabel_fontsize', None)
9911010
ylabel = plot_args.get('ylabel', 'Number of catalogs')
1011+
ylabel_fontsize = plot_args.get('ylabel_fontsize', None)
1012+
text_fontsize = plot_args.get('text_fontsize', 14)
1013+
tight_layout = plot_args.get('tight_layout', True)
1014+
percentile = plot_args.get('percentile', 95)
1015+
filename = plot_args.get('filename', None)
1016+
bins = plot_args.get('bins', 'auto')
9921017
xy = plot_args.get('xy', (0.5, 0.3))
9931018

1019+
# set default plotting arguments
9941020
fixed_plot_args = {'obs_label': evaluation_result.obs_name,
9951021
'sim_label': evaluation_result.sim_name}
9961022
plot_args.update(fixed_plot_args)
997-
bins = plot_args.get('mag_bins', 'auto')
998-
percentile = plot_args.get('percentile', 95)
9991023
ax = plot_histogram(evaluation_result.test_distribution, evaluation_result.observed_statistic,
10001024
catalog=evaluation_result.obs_catalog_repr,
10011025
plot_args=plot_args,
@@ -1010,18 +1034,20 @@ def plot_number_test(evaluation_result, axes=None, show=True, plot_args=None):
10101034
.format(*evaluation_result.quantile, evaluation_result.observed_statistic),
10111035
xycoords='axes fraction',
10121036
xy=xy,
1013-
fontsize=14)
1037+
fontsize=text_fontsize)
10141038
except:
10151039
ax.annotate('$\gamma = P(X \leq x) = {:.2f}$\n$\omega = {:.2f}$'
10161040
.format(evaluation_result.quantile, evaluation_result.observed_statistic),
10171041
xycoords='axes fraction',
10181042
xy=xy,
1019-
fontsize=14)
1043+
fontsize=text_fontsize)
10201044

1021-
title = plot_args.get('title', evaluation_result.name)
1022-
ax.set_title(title, fontsize=14)
1023-
ax.set_xlabel(xlabel)
1024-
ax.set_ylabel(ylabel)
1045+
ax.set_title(title, fontsize=title_fontsize)
1046+
ax.set_xlabel(xlabel, fontsize=xlabel_fontsize)
1047+
ax.set_ylabel(ylabel, fontsize=ylabel_fontsize)
1048+
1049+
if tight_layout:
1050+
ax.figure.tight_layout()
10251051

10261052
if filename is not None:
10271053
ax.figure.savefig(filename + '.pdf')
@@ -1040,31 +1066,54 @@ def plot_magnitude_test(evaluation_result, axes=None, show=True, plot_args=None)
10401066
Takes result from evaluation and generates a specific histogram plot to show the results of the statistical evaluation
10411067
for the M-test.
10421068
1043-
10441069
Args:
1045-
evaluation_result: object that implements the interface of EvaluationResult
1070+
evaluation_result: object-like var that implements the interface of the above EvaluationResult
1071+
axes (matplotlib.Axes): axes object used to chain this plot
1072+
show (bool): if true, call pyplot.show()
1073+
plot_args(dict): optional argument containing a dictionary of plotting arguments, with keys as strings and items as described below
1074+
1075+
Optional plotting arguments:
1076+
* figsize: (:class:`list`/:class:`tuple`) - default: [6.4, 4.8]
1077+
* title: (:class:`str`) - default: name of the first evaluation result type
1078+
* title_fontsize: (:class:`float`) Fontsize of the plot title - default: 10
1079+
* xlabel: (:class:`str`) - default: 'X'
1080+
* xlabel_fontsize: (:class:`float`) - default: 10
1081+
* xticks_fontsize: (:class:`float`) - default: 10
1082+
* ylabel_fontsize: (:class:`float`) - default: 10
1083+
* tight_layout: (:class:`bool`) Set matplotlib.figure.tight_layout to remove excess blank space in the plot - default: True
1084+
* percentile (:class:`float`) Critial region to shade on histogram - default: 95
1085+
* bins: (:class:`str`) - Set binning type. see matplotlib.hist for more info - default: 'auto'
1086+
* xy: (:class:`list`/:class:`tuple`) - default: (0.55, 0.6)
10461087
10471088
Returns:
1048-
ax (matplotlib.axes.Axes): can be used to modify the figure
1089+
ax (matplotlib.Axes): containing the new plot
10491090
10501091
"""
10511092
plot_args = plot_args or {}
1093+
title = plot_args.get('title', 'Magnitude Test')
1094+
title_fontsize = plot_args.get('title_fontsize', None)
1095+
xlabel = plot_args.get('xlabel', 'D* Statistic')
1096+
xlabel_fontsize = plot_args.get('xlabel_fontsize', None)
1097+
ylabel = plot_args.get('ylabel', 'Number of catalogs')
1098+
ylabel_fontsize = plot_args.get('ylabel_fontsize', None)
1099+
tight_layout = plot_args.get('tight_layout', True)
1100+
percentile = plot_args.get('percentile', 95)
1101+
text_fontsize = plot_args.get('text_fontsize', 14)
1102+
filename = plot_args.get('filename', None)
1103+
bins = plot_args.get('bins', 'auto')
1104+
xy = plot_args.get('xy', (0.55, 0.6))
1105+
10521106
# handle plotting
10531107
if axes:
10541108
chained = True
10551109
else:
10561110
chained = False
1111+
10571112
# supply fixed arguments to plots
10581113
# might want to add other defaults here
1059-
filename = plot_args.get('filename', None)
1060-
xy = plot_args.get('xy', (0.55, 0.6))
1061-
fixed_plot_args = {'xlabel': 'D* Statistic',
1062-
'ylabel': 'Number of Catalogs',
1063-
'obs_label': evaluation_result.obs_name,
1114+
fixed_plot_args = {'obs_label': evaluation_result.obs_name,
10641115
'sim_label': evaluation_result.sim_name}
10651116
plot_args.update(fixed_plot_args)
1066-
bins = plot_args.get('bins', 'auto')
1067-
percentile = plot_args.get('percentile', 95)
10681117
ax = plot_histogram(evaluation_result.test_distribution, evaluation_result.observed_statistic,
10691118
catalog=evaluation_result.obs_catalog_repr,
10701119
plot_args=plot_args,
@@ -1079,17 +1128,22 @@ def plot_magnitude_test(evaluation_result, axes=None, show=True, plot_args=None)
10791128
.format(evaluation_result.quantile, evaluation_result.observed_statistic),
10801129
xycoords='axes fraction',
10811130
xy=xy,
1082-
fontsize=14)
1131+
fontsize=text_fontsize)
10831132
except TypeError:
10841133
# if both quantiles are provided, we want to plot the greater-equal quantile
10851134
ax.annotate('$\gamma = P(X \geq x) = {:.2f}$\n$\omega = {:.2f}$'
10861135
.format(evaluation_result.quantile[0], evaluation_result.observed_statistic),
10871136
xycoords='axes fraction',
10881137
xy=xy,
1089-
fontsize=14)
1138+
fontsize=text_fontsize)
10901139

1091-
title = plot_args.get('title', 'Magnitude Test')
1092-
ax.set_title(title, fontsize=14)
1140+
ax.set_title(title, fontsize=title_fontsize)
1141+
ax.set_xlabel(xlabel, fontsize=xlabel_fontsize)
1142+
ax.set_ylabel(ylabel, fontsize=ylabel_fontsize)
1143+
1144+
if tight_layout:
1145+
var = ax.get_figure().tight_layout
1146+
()
10931147

10941148
if filename is not None:
10951149
ax.figure.savefig(filename + '.pdf')
@@ -1149,7 +1203,6 @@ def plot_distribution_test(evaluation_result, axes=None, show=True, plot_args=No
11491203

11501204
title = plot_args.get('title', evaluation_result.name)
11511205
ax.set_title(title, fontsize=14)
1152-
ax.set_title(title, fontsize=14)
11531206
ax.set_xlabel(xlabel)
11541207
ax.set_ylabel(ylabel)
11551208

@@ -1170,30 +1223,53 @@ def plot_likelihood_test(evaluation_result, axes=None, show=True, plot_args=None
11701223
Takes result from evaluation and generates a specific histogram plot to show the results of the statistical evaluation
11711224
for the L-test.
11721225
1173-
11741226
Args:
11751227
evaluation_result: object-like var that implements the interface of the above EvaluationResult
1228+
axes (matplotlib.Axes): axes object used to chain this plot
1229+
show (bool): if true, call pyplot.show()
1230+
plot_args(dict): optional argument containing a dictionary of plotting arguments, with keys as strings and items as described below
1231+
1232+
Optional plotting arguments:
1233+
* figsize: (:class:`list`/:class:`tuple`) - default: [6.4, 4.8]
1234+
* title: (:class:`str`) - default: name of the first evaluation result type
1235+
* title_fontsize: (:class:`float`) Fontsize of the plot title - default: 10
1236+
* xlabel: (:class:`str`) - default: 'X'
1237+
* xlabel_fontsize: (:class:`float`) - default: 10
1238+
* xticks_fontsize: (:class:`float`) - default: 10
1239+
* ylabel_fontsize: (:class:`float`) - default: 10
1240+
* text_fontsize: (:class:`float`) - default: 14
1241+
* tight_layout: (:class:`bool`) Set matplotlib.figure.tight_layout to remove excess blank space in the plot - default: True
1242+
* percentile (:class:`float`) Critial region to shade on histogram - default: 95
1243+
* bins: (:class:`str`) - Set binning type. see matplotlib.hist for more info - default: 'auto'
1244+
* xy: (:class:`list`/:class:`tuple`) - default: (0.55, 0.3)
11761245
11771246
Returns:
11781247
ax (matplotlib.axes.Axes): can be used to modify the figure
1179-
11801248
"""
11811249
plot_args = plot_args or {}
1250+
title = plot_args.get('title', 'Pseudo-likelihood Test')
1251+
title_fontsize = plot_args.get('title_fontsize', None)
1252+
xlabel = plot_args.get('xlabel', 'Pseudo likelihood')
1253+
xlabel_fontsize = plot_args.get('xlabel_fontsize', None)
1254+
ylabel = plot_args.get('ylabel', 'Number of catalogs')
1255+
ylabel_fontsize = plot_args.get('ylabel_fontsize', None)
1256+
text_fontsize = plot_args.get('text_fontsize', 14)
1257+
tight_layout = plot_args.get('tight_layout', True)
1258+
percentile = plot_args.get('percentile', 95)
1259+
filename = plot_args.get('filename', None)
1260+
bins = plot_args.get('bins', 'auto')
1261+
xy = plot_args.get('xy', (0.55, 0.3))
1262+
11821263
# handle plotting
11831264
if axes:
11841265
chained = True
11851266
else:
11861267
chained = False
11871268
# supply fixed arguments to plots
11881269
# might want to add other defaults here
1189-
filename = plot_args.get('filename', None)
1190-
fixed_plot_args = {'xlabel': 'Pseudo likelihood',
1191-
'ylabel': 'Number of catalogs',
1192-
'obs_label': evaluation_result.obs_name,
1270+
fixed_plot_args = {'obs_label': evaluation_result.obs_name,
11931271
'sim_label': evaluation_result.sim_name}
11941272
plot_args.update(fixed_plot_args)
1195-
bins = plot_args.get('bins', 'auto')
1196-
percentile = plot_args.get('percentile', 95)
11971273
ax = plot_histogram(evaluation_result.test_distribution, evaluation_result.observed_statistic,
11981274
catalog=evaluation_result.obs_catalog_repr,
11991275
plot_args=plot_args,
@@ -1207,19 +1283,22 @@ def plot_likelihood_test(evaluation_result, axes=None, show=True, plot_args=None
12071283
ax.annotate('$\gamma = P(X \leq x) = {:.2f}$\n$\omega = {:.2f}$'
12081284
.format(evaluation_result.quantile, evaluation_result.observed_statistic),
12091285
xycoords='axes fraction',
1210-
xy=(0.55, 0.3),
1211-
fontsize=14)
1286+
xy=xy,
1287+
fontsize=text_fontsize)
12121288
except TypeError:
12131289
# if both quantiles are provided, we want to plot the greater-equal quantile
12141290
ax.annotate('$\gamma = P(X \leq x) = {:.2f}$\n$\omega = {:.2f}$'
12151291
.format(evaluation_result.quantile[1], evaluation_result.observed_statistic),
12161292
xycoords='axes fraction',
1217-
xy=(0.55, 0.3),
1218-
fontsize=14)
1293+
xy=xy,
1294+
fontsize=text_fontsize)
12191295

1296+
ax.set_title(title, fontsize=title_fontsize)
1297+
ax.set_xlabel(xlabel, fontsize=xlabel_fontsize)
1298+
ax.set_ylabel(ylabel, fontsize=ylabel_fontsize)
12201299

1221-
title = plot_args.get('title', 'Likelihood Test')
1222-
ax.set_title(title, fontsize=14)
1300+
if tight_layout:
1301+
ax.figure.tight_layout()
12231302

12241303
if filename is not None:
12251304
ax.figure.savefig(filename + '.pdf')
@@ -1237,31 +1316,59 @@ def plot_spatial_test(evaluation_result, axes=None, plot_args=None, show=True):
12371316
Plot spatial test result from catalog based forecast
12381317
12391318
Args:
1240-
evaluation_result:
1319+
evaluation_result: object-like var that implements the interface of the above EvaluationResult
1320+
axes (matplotlib.Axes): axes object used to chain this plot
1321+
show (bool): if true, call pyplot.show()
1322+
plot_args(dict): optional argument containing a dictionary of plotting arguments, with keys as strings and items as described below
12411323
1242-
Returns:
1324+
Optional plotting arguments:
1325+
* figsize: (:class:`list`/:class:`tuple`) - default: [6.4, 4.8]
1326+
* title: (:class:`str`) - default: name of the first evaluation result type
1327+
* title_fontsize: (:class:`float`) Fontsize of the plot title - default: 10
1328+
* xlabel: (:class:`str`) - default: 'X'
1329+
* xlabel_fontsize: (:class:`float`) - default: 10
1330+
* xticks_fontsize: (:class:`float`) - default: 10
1331+
* ylabel_fontsize: (:class:`float`) - default: 10
1332+
* text_fontsize: (:class:`float`) - default: 14
1333+
* tight_layout: (:class:`bool`) Set matplotlib.figure.tight_layout to remove excess blank space in the plot - default: True
1334+
* percentile (:class:`float`) Critial region to shade on histogram - default: 95
1335+
* bins: (:class:`str`) - Set binning type. see matplotlib.hist for more info - default: 'auto'
1336+
* xy: (:class:`list`/:class:`tuple`) - default: (0.2, 0.6)
12431337
1338+
Returns:
1339+
ax (matplotlib.axes.Axes): can be used to modify the figure
12441340
"""
1341+
12451342
plot_args = plot_args or {}
1343+
title = plot_args.get('title', 'Spatial Test')
1344+
title_fontsize = plot_args.get('title_fontsize', None)
1345+
xlabel = plot_args.get('xlabel', 'Normalized pseudo-likelihood')
1346+
xlabel_fontsize = plot_args.get('xlabel_fontsize', None)
1347+
ylabel = plot_args.get('ylabel', 'Number of catalogs')
1348+
ylabel_fontsize = plot_args.get('ylabel_fontsize', None)
1349+
text_fontsize = plot_args.get('text_fontsize', 14)
1350+
tight_layout = plot_args.get('tight_layout', True)
1351+
percentile = plot_args.get('percentile', 95)
1352+
filename = plot_args.get('filename', None)
1353+
bins = plot_args.get('bins', 'auto')
1354+
xy = plot_args.get('xy', (0.2, 0.6))
1355+
12461356
# handle plotting
12471357
if axes:
12481358
chained = True
12491359
else:
12501360
chained = False
1361+
12511362
# supply fixed arguments to plots
12521363
# might want to add other defaults here
1253-
filename = plot_args.get('filename', None)
12541364
fixed_plot_args = {'obs_label': evaluation_result.obs_name,
1255-
'sim_label': evaluation_result.sim_name,
1256-
'xlabel': 'Normalized pseudo likelihood',
1257-
'ylabel': 'Number of catalogs'}
1365+
'sim_label': evaluation_result.sim_name}
12581366
plot_args.update(fixed_plot_args)
1259-
title = plot_args.get('title', 'Spatial Test')
1260-
percentile = plot_args.get('percentile', 95)
1367+
12611368
ax = plot_histogram(evaluation_result.test_distribution, evaluation_result.observed_statistic,
12621369
catalog=evaluation_result.obs_catalog_repr,
12631370
plot_args=plot_args,
1264-
bins='fd',
1371+
bins=bins,
12651372
axes=axes,
12661373
percentile=percentile)
12671374

@@ -1271,18 +1378,22 @@ def plot_spatial_test(evaluation_result, axes=None, plot_args=None, show=True):
12711378
ax.annotate('$\gamma = P(X \leq x) = {:.2f}$\n$\omega = {:.2f}$'
12721379
.format(evaluation_result.quantile, evaluation_result.observed_statistic),
12731380
xycoords='axes fraction',
1274-
xy=(0.2, 0.6),
1275-
fontsize=14)
1381+
xy=xy,
1382+
fontsize=text_fontsize)
12761383
except TypeError:
12771384
# if both quantiles are provided, we want to plot the greater-equal quantile
12781385
ax.annotate('$\gamma = P(X \leq x) = {:.2f}$\n$\omega = {:.2f}$'
12791386
.format(evaluation_result.quantile[1], evaluation_result.observed_statistic),
12801387
xycoords='axes fraction',
1281-
xy=(0.2, 0.6),
1282-
fontsize=14)
1388+
xy=xy,
1389+
fontsize=text_fontsize)
12831390

1391+
ax.set_title(title, fontsize=title_fontsize)
1392+
ax.set_xlabel(xlabel, fontsize=xlabel_fontsize)
1393+
ax.set_ylabel(ylabel, fontsize=ylabel_fontsize)
12841394

1285-
ax.set_title(title, fontsize=14)
1395+
if tight_layout:
1396+
ax.figure.tight_layout()
12861397

12871398
if filename is not None:
12881399
ax.figure.savefig(filename + '.pdf')

0 commit comments

Comments
 (0)