Skip to content

Commit b753779

Browse files
authored
Merge pull request PSLmodels#1024 from jdebacker/plot_tables
Merging
2 parents e51a130 + 70c107f commit b753779

14 files changed

Lines changed: 191 additions & 170 deletions

CHANGELOG.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,16 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

88

9+
## [0.14.2] - 2025-04-04 12:00:00
10+
11+
### Added
12+
13+
- `utils.pct_change_unstationarized` replaced with `utils.unstationarize_vars`, which allows for more general use of a utility to find unstationarized values of time series output
14+
- `output_plots.py` and `output_tables.py` are updated to all for plots and tables of unstationarized output for variables of any type, not just percentage changes.
15+
- `ouput_tables.tp_output_dump_table` has been renamed `output_tables.time_series_table`
16+
- `utils.param_dump_json` has been renamed `utils.params_to_json`
17+
- API docs have been updated to include functions left out previously and for new function names
18+
919
## [0.14.1] - 2025-03-16 12:00:00
1020

1121
### Bug Fix
@@ -363,6 +373,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
363373
- Version [0.7.0] on August 30, 2021 was the first time that the OG-USA repository was detached from all of the core model logic, which was named OG-Core. Before this version, OG-USA was part of what is now the [`OG-Core`](https://github.com/PSLmodels/OG-Core) repository. In the next version of OG-USA, we adjusted the version numbering to begin with 0.1.0. This initial version of 0.7.0, was sequential from what OG-USA used to be when the OG-Core project was called OG-USA.
364374
- Any earlier versions of OG-USA can be found in the [`OG-Core`](https://github.com/PSLmodels/OG-Core) repository [release history](https://github.com/PSLmodels/OG-Core/releases) from [v.0.6.4](https://github.com/PSLmodels/OG-Core/releases/tag/v0.6.4) (Jul. 20, 2021) or earlier.
365375

376+
[0.14.2]: https://github.com/PSLmodels/OG-Core/compare/v0.14.1...v0.14.2
366377
[0.14.1]: https://github.com/PSLmodels/OG-Core/compare/v0.14.0...v0.14.1
367378
[0.14.0]: https://github.com/PSLmodels/OG-Core/compare/v0.13.2...v0.14.0
368379
[0.13.2]: https://github.com/PSLmodels/OG-Core/compare/v0.13.1...v0.13.2

README.md

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,18 @@
33
| | |
44
| --- | --- |
55
| Org | [![PSL cataloged](https://img.shields.io/badge/PSL-cataloged-a0a0a0.svg)](https://www.PSLmodels.org) [![OS License: CCO-1.0](https://img.shields.io/badge/OS%20License-CCO%201.0-yellow)](https://github.com/PSLmodels/OG-Core/blob/master/LICENSE) [![Jupyter Book Badge](https://jupyterbook.org/badge.svg)](https://pslmodels.github.io/OG-Core/) |
6-
| Package | [![Python 3.9](https://img.shields.io/badge/python-3.9-blue.svg)](https://www.python.org/downloads/release/python-3916/) [![Python 3.10](https://img.shields.io/badge/python-3.10-blue.svg)](https://www.python.org/downloads/release/python-3108/) [![Python 3.11](https://img.shields.io/badge/python-3.10-blue.svg)](https://www.python.org/downloads/release/python-3118/) [![PyPI Latest Release](https://img.shields.io/pypi/v/ogcore.svg)](https://pypi.org/project/ogcore/) [![PyPI Downloads](https://img.shields.io/pypi/dm/ogcore.svg?label=PyPI%20downloads)](https://pypi.org/project/ogcore/) [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black) |
6+
| Package | [![Python 3.11](https://img.shields.io/badge/python-3.11-blue.svg)](https://www.python.org/downloads/release/python-31111/) [![Python 3.12](https://img.shields.io/badge/python-3.12-blue.svg)](https://www.python.org/downloads/release/python-3129/) [![PyPI Latest Release](https://img.shields.io/pypi/v/ogcore.svg)](https://pypi.org/project/ogcore/) [![PyPI Downloads](https://img.shields.io/pypi/dm/ogcore.svg?label=PyPI%20downloads)](https://pypi.org/project/ogcore/) [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black) |
77
| Testing | ![example event parameter](https://github.com/PSLmodels/OG-Core/actions/workflows/build_and_test.yml/badge.svg?branch=master) ![example event parameter](https://github.com/PSLmodels/OG-Core/actions/workflows/deploy_docs.yml/badge.svg?branch=master) ![example event parameter](https://github.com/PSLmodels/OG-Core/actions/workflows/check_black.yml/badge.svg?branch=master) [![Codecov](https://codecov.io/gh/PSLmodels/OG-Core/branch/master/graph/badge.svg)](https://codecov.io/gh/PSLmodels/OG-Core) |
88

99

10-
OG-Core is an overlapping-generations (OG) model core theory, logic, and solution method algorithms that allow for dynamic general equilibrium analysis of fiscal policy. OG-Core provides a general framework and is a dependency of several country-specific OG models, such as [OG-USA](https://github.com/PSLmodels/OG-USA) and [OG-UK](https://github.com/PSLmodels/OG-UK). The model output includes changes in macroeconomic aggregates (GDP, investment, consumption), wages, interest rates, and the stream of tax revenues over time. Regularly updated documentation of the model theory--its output, and solution method--and the Python API is available [here](https://pslmodels.github.io/OG-Core).
10+
OG-Core is an overlapping-generations (OG) model core theory, logic, and solution method algorithms that allow for dynamic general equilibrium analysis of fiscal policy. OG-Core provides a general framework and is a dependency of several country-specific OG model caliibrations, as listed in the table belowsuch as [OG-USA](https://github.com/PSLmodels/OG-USA) and [OG-UK](https://github.com/PSLmodels/OG-UK). The model output includes changes in macroeconomic aggregates (GDP, investment, consumption), wages, interest rates, and the stream of tax revenues over time. Regularly updated documentation of the model theory--its output, and solution method--and the Python API is available [here](https://pslmodels.github.io/OG-Core).
11+
12+
**Country calibrations of OG-Core**
13+
| | | |
14+
| :-----------: | :---------: | :---------: |
15+
| United States, [OG-USA](https://github.com/PSLmodels/OG-USA) | United Kingdom, [OG-UK](https://github.com/PSLmodels/OG-USA) | |
16+
| Phillipines, [OG-PHL](https://github.com/EAPD-DRB/OG-PHL) | South Africa, [OG-ZAF](https://github.com/EAPD-DRB/OG-ZAF) | Indonesia, [OG-IDN](https://github.com/EAPD-DRB/OG-IDN) |
17+
| India, [OG-IND](https://github.com/OpenSourceEcon/OG-IND) | Malaysia, [OG-MYS](https://github.com/OpenSourceEcon/OG-MYS) | |
1118

1219

1320
## Disclaimer

docs/book/content/api/output_plots.rst

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,5 +9,6 @@ ogcore.output_plots
99
------------------------------------------
1010

1111
.. automodule:: ogcore.output_plots
12-
:members: plot_aggregates, plot_gdp_ratio, ability_bar, ability_bar_ss,
13-
ss_profiles, tpi_profiles, plot_all
12+
:members: plot_aggregates, plot_industry_aggregates, ss_3Dplot,
13+
plot_gdp_ratio, ability_bar, ability_bar_ss,
14+
tpi_profiles, ss_profiles, plot_all, inequality_plot, lambda_labels

docs/book/content/api/output_tables.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,5 @@ ogcore.output_tables
1010

1111
.. automodule:: ogcore.output_tables
1212
:members: macro_table, macro_table_SS, ineq_table, gini_table,
13-
wealth_moments_table, tp_output_dump_table, dynamic_revenue_decomposition
13+
wealth_moments_table, time_series_table,
14+
dynamic_revenue_decomposition

docs/book/content/api/parameter_plots.rst

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,9 @@ ogcore.parameter_plots
1010

1111
.. automodule:: ogcore.parameter_plots
1212
:members: plot_imm_rates, plot_mort_rates, plot_pop_growth,
13-
plot_ability_profiles, plot_elliptical_u, plot_chi_n,
14-
plot_fert_rates, plot_mort_rates_data, plot_g_n, plot_omega_fixed,
15-
plot_imm_fixed, plot_population_path, gen_3Dscatters_hist,
16-
txfunc_graph, txfunc_sse_plot, plot_income_data, plot_2D_taxfunc
13+
plot_population, plot_ability_profiles, plot_elliptical_u,
14+
plot_chi_n, plot_fert_rates, plot_mort_rates_data, plot_g_n,
15+
plot_omega_fixed, plot_imm_fixed, plot_population_path,
16+
gen_3Dscatters_hist, txfunc_graph, txfunc_sse_plot,
17+
plot_income_data, plot_2D_taxfunc
1718

docs/book/content/api/utils.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,4 @@ ogcore.utils
2222
to_timepath_shape, get_initial_path, safe_read_pickle, rate_conversion,
2323
save_return_table, print_progress, fetch_files_from_web, not_connected,
2424
avg_by_bin, extrapolate_arrays, get_legacy_session, shift_bio_clock,
25-
pct_change_unstationarized, param_dump_json
25+
unstationarize_vars, params_to_json

docs/book/content/intro/intro.md

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,18 @@
44
| | |
55
| --- | --- |
66
| Org | [![PSL cataloged](https://img.shields.io/badge/PSL-cataloged-a0a0a0.svg)](https://www.PSLmodels.org) [![OS License: CCO-1.0](https://img.shields.io/badge/OS%20License-CCO%201.0-yellow)](https://github.com/PSLmodels/OG-Core/blob/master/LICENSE) [![Jupyter Book Badge](https://jupyterbook.org/badge.svg)](https://pslmodels.github.io/OG-Core/) |
7-
| Package | [![Python 3.9](https://img.shields.io/badge/python-3.9-blue.svg)](https://www.python.org/downloads/release/python-3916/) [![Python 3.10](https://img.shields.io/badge/python-3.10-blue.svg)](https://www.python.org/downloads/release/python-3108/) [![Python 3.11](https://img.shields.io/badge/python-3.10-blue.svg)](https://www.python.org/downloads/release/python-3118/) [![PyPI Latest Release](https://img.shields.io/pypi/v/ogcore.svg)](https://pypi.org/project/ogcore/) [![PyPI Downloads](https://img.shields.io/pypi/dm/ogcore.svg?label=PyPI%20downloads)](https://pypi.org/project/ogcore/) [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black) |
7+
| Package | [![Python 3.11](https://img.shields.io/badge/python-3.11-blue.svg)](https://www.python.org/downloads/release/python-31111/) [![Python 3.12](https://img.shields.io/badge/python-3.12-blue.svg)](https://www.python.org/downloads/release/python-3129/) [![PyPI Latest Release](https://img.shields.io/pypi/v/ogcore.svg)](https://pypi.org/project/ogcore/) [![PyPI Downloads](https://img.shields.io/pypi/dm/ogcore.svg?label=PyPI%20downloads)](https://pypi.org/project/ogcore/) [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black) |
88
| Testing | ![example event parameter](https://github.com/PSLmodels/OG-Core/actions/workflows/build_and_test.yml/badge.svg?branch=master) ![example event parameter](https://github.com/PSLmodels/OG-Core/actions/workflows/deploy_docs.yml/badge.svg?branch=master) ![example event parameter](https://github.com/PSLmodels/OG-Core/actions/workflows/check_black.yml/badge.svg?branch=master) [![Codecov](https://codecov.io/gh/PSLmodels/OG-Core/branch/master/graph/badge.svg)](https://codecov.io/gh/PSLmodels/OG-Core) |
99

1010
`OG-Core` is the core logic for a country-agnostic overlapping-generations (OG) model of an economy that allows for dynamic general equilibrium analysis of fiscal policy. The source code is openly available for download or collaboration at the GitHub repository [www.github.com/PSLmodels/OG-Core](https://github.com/PSLmodels/OG-Core), or you can click on the GitHub icon at the top right of this page.
1111

12+
**Country calibrations of OG-Core**
13+
| | | |
14+
| :-----------: | :---------: | :---------: |
15+
| United States, [OG-USA](https://github.com/PSLmodels/OG-USA) | United Kingdom, [OG-UK](https://github.com/PSLmodels/OG-USA) | |
16+
| Phillipines, [OG-PHL](https://github.com/EAPD-DRB/OG-PHL) | South Africa, [OG-ZAF](https://github.com/EAPD-DRB/OG-ZAF) | Indonesia, [OG-IDN](https://github.com/EAPD-DRB/OG-IDN) |
17+
| India, [OG-IND](https://github.com/OpenSourceEcon/OG-IND) | Malaysia, [OG-MYS](https://github.com/OpenSourceEcon/OG-MYS) | |
18+
1219
The model output focuses changes in macroeconomic aggregates (GDP, investment, consumption), wages, interest rates, and the stream of tax revenues over time. Although `OG-Core` can be run independently based on default parameter values (currently representing something similar to the United States), it is meant to be a dependency of a country-specific calibration. This documentation contains the following major sections, which are regularly updated.
1320

1421
* Contributing to `OG-Core`

ogcore/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,4 @@
2020
from ogcore.txfunc import *
2121
from ogcore.utils import *
2222

23-
__version__ = "0.14.1"
23+
__version__ = "0.14.2"

ogcore/output_plots.py

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,7 @@ def plot_aggregates(
4848
'levels': plot variables in model units
4949
'forecast': plots variables in levels relative to baseline
5050
economic forecast
51-
stationarized (bool): whether used stationarized variables (False
52-
only affects pct_diff right now)
51+
stationarized (bool): whether used stationarized variables
5352
num_years_to_plot (integer): number of years to include in plot
5453
start_year (integer): year to start plot
5554
forecast_data (array_like): baseline economic forecast series,
@@ -76,6 +75,13 @@ def plot_aggregates(
7675
if plot_type == "pct_diff" or plot_type == "diff":
7776
assert reform_tpi is not None
7877
fig1, ax1 = plt.subplots()
78+
if not stationarized:
79+
for v in var_list:
80+
base_tpi[v] = utils.unstationarize_vars(v, base_tpi, base_params)
81+
if reform_tpi:
82+
reform_tpi[v] = utils.unstationarize_vars(
83+
v, reform_tpi, reform_params
84+
)
7985
for i, v in enumerate(var_list):
8086
assert (
8187
v in VAR_LABELS.keys()
@@ -85,17 +91,7 @@ def plot_aggregates(
8591
# Compute just percentage point changes for rates
8692
plot_var = reform_tpi[v] - base_tpi[v]
8793
else:
88-
if stationarized:
89-
plot_var = (reform_tpi[v] - base_tpi[v]) / base_tpi[v]
90-
else:
91-
pct_changes = utils.pct_change_unstationarized(
92-
base_tpi,
93-
base_params,
94-
reform_tpi,
95-
reform_params,
96-
output_vars=[v],
97-
)
98-
plot_var = pct_changes[v]
94+
plot_var = (reform_tpi[v] - base_tpi[v]) / base_tpi[v]
9995
ylabel = r"Pct. change"
10096
plt.plot(
10197
year_vec,
@@ -182,6 +178,7 @@ def plot_industry_aggregates(
182178
var_list=["Y_m"],
183179
ind_names_list=None,
184180
plot_type="pct_diff",
181+
stationarized=True,
185182
num_years_to_plot=50,
186183
start_year=DEFAULT_START_YEAR,
187184
forecast_data=None,
@@ -201,6 +198,7 @@ def plot_industry_aggregates(
201198
reform_params (OG-Core Specifications class): reform parameters
202199
object
203200
var_list (list): names of variable to plot
201+
204202
plot_type (string): type of plot, can be:
205203
'pct_diff': plots percentage difference between baseline
206204
and reform ((reform-base)/base)
@@ -209,6 +207,7 @@ def plot_industry_aggregates(
209207
'levels': plot variables in model units
210208
'forecast': plots variables in levels relative to baseline
211209
economic forecast
210+
stationarized (bool): whether used stationarized variables
212211
num_years_to_plot (integer): number of years to include in plot
213212
start_year (integer): year to start plot
214213
forecast_data (array_like): baseline economic forecast series,
@@ -236,6 +235,14 @@ def plot_industry_aggregates(
236235
assert base_params.start_year == reform_params.start_year
237236
year_vec = np.arange(start_year, start_year + num_years_to_plot)
238237
start_index = start_year - base_params.start_year
238+
# Unstationarize variables if needed
239+
if not stationarized:
240+
for v in var_list:
241+
base_tpi[v] = utils.unstationarize_vars(v, base_tpi, base_params)
242+
if reform_tpi:
243+
reform_tpi[v] = utils.unstationarize_vars(
244+
v, reform_tpi, reform_params
245+
)
239246
# Check that reform included if doing pct_diff or diff plot
240247
if plot_type == "pct_diff" or plot_type == "diff":
241248
assert reform_tpi is not None

ogcore/output_tables.py

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from ogcore.constants import VAR_LABELS, DEFAULT_START_YEAR
55
from ogcore import tax
66
from ogcore.utils import save_return_table, Inequality
7-
from ogcore.utils import pct_change_unstationarized
7+
from ogcore.utils import unstationarize_vars
88

99
cur_path = os.path.split(os.path.abspath(__file__))[0]
1010

@@ -64,6 +64,13 @@ def macro_table(
6464
assert base_params.start_year == reform_params.start_year
6565
year_vec = np.arange(start_year, start_year + num_years)
6666
start_index = start_year - base_params.start_year
67+
if not stationarized:
68+
for v in var_list:
69+
base_tpi[v] = unstationarize_vars(v, base_tpi, base_params)
70+
if reform_tpi:
71+
reform_tpi[v] = unstationarize_vars(
72+
v, reform_tpi, reform_params
73+
)
6774
# Check that reform included if doing pct_diff or diff plot
6875
if output_type == "pct_diff" or output_type == "diff":
6976
assert reform_tpi is not None
@@ -76,17 +83,7 @@ def macro_table(
7683
for i, v in enumerate(var_list):
7784
if output_type == "pct_diff":
7885
# multiple by 100 so in percentage points
79-
if stationarized:
80-
results = ((reform_tpi[v] - base_tpi[v]) / base_tpi[v]) * 100
81-
else:
82-
pct_changes = pct_change_unstationarized(
83-
base_tpi,
84-
base_params,
85-
reform_tpi,
86-
reform_params,
87-
output_vars=[v],
88-
)
89-
results = pct_changes[v] * 100
86+
results = ((reform_tpi[v] - base_tpi[v]) / base_tpi[v]) * 100
9087
results_years = results[start_index : start_index + num_years]
9188
results_overall = (
9289
(
@@ -452,11 +449,12 @@ def wealth_moments_table(
452449
return table
453450

454451

455-
def tp_output_dump_table(
452+
def time_series_table(
456453
base_params,
457454
base_tpi,
458455
reform_params=None,
459456
reform_tpi=None,
457+
stationarized=True,
460458
table_format=None,
461459
path=None,
462460
):
@@ -471,6 +469,7 @@ def tp_output_dump_table(
471469
reform_params (OG-Core Specifications class): reform parameters
472470
object
473471
reform_tpi (dictionary): TP output from reform run
472+
stationarized (bool): whether to report stationarized output
474473
table_format (string): format to return table in: 'csv', 'tex',
475474
'excel', 'json', if None, a DataFrame is returned
476475
path (string): path to save table to
@@ -501,6 +500,14 @@ def tp_output_dump_table(
501500
"total_tax_revenue",
502501
"business_tax_revenue",
503502
]
503+
# unstationarize variables if needed
504+
if not stationarized:
505+
for v in vars_to_keep:
506+
base_tpi[v] = unstationarize_vars(v, base_tpi, base_params)
507+
if reform_tpi:
508+
reform_tpi[v] = unstationarize_vars(
509+
v, reform_tpi, reform_params
510+
)
504511
base_dict = {k: base_tpi[k] for k in vars_to_keep}
505512
# update key names
506513
base_dict_final = dict(

0 commit comments

Comments
 (0)