Skip to content

Commit 0294a7e

Browse files
cdelinemdecegliemartin-springerCopilot
authored
Multi yoy integration - combines PRs #456, #460 and #464 at once. (#470)
* add keyword 'label' to degradation_timeseries_plot, enabling 'left' and 'center' labeling options. * Update changelog, add pytests, update sphinx documentation * fix flake8 grumbles * update pytests to include axes limits * fix flake8 grumbles * add 'label' input option to `degradation_year_on_year`. Fixes #459 * add pytests and update changelog. * flake8 grumbles * Minor updates to setup.py (constrain scipy<1.16) and refactor degradation_test * Custom fix for Pandas < 2.0.0 which can't average two columns of timestamps. * flake8 grumbles * keep TZ-aware timestamps. Update pytests to specifically test _avg_timestamp_old_Pandas * flake8 grumbles * try to UTC localize the pytest... * Add .asfreq() to get pytests to agree * switch to calendar.timegm to hopefully remove TZ issues.. * regardless of uncertainty_method, return calc_info{'YoY_values') * update _right dt labels to correct _left labels in degradation_year_on_year * update _avg_timestamp_old_Pandas to allow for numeric index instead of timestamp * add left label option to degradation_year_on_year * update degradation_year_on_year, index set to either left, center or right. Consistent with #394 - multi_yoy * update return for default = none uncertainty option * degradation_year_on_year - go back to single return when uncertainty_value = None to avoid breaking pytests. * add multi-year aggregation of slopes in degradation_year_on_year * add multi_yoy kwarg in degradation_year_on_year to toggle the multi-YoY function. * update plotting for detailed=True, allow usage_of_points > 2 * flake8 grumbles * update plotting detailed=True for (even) and (odd) number of points coloring * To allow multi_yoy=True in plotting.degradation_timeseries_plot, resample.mean() the YoY_values. * flake8 grumbles * Add warning to degradation_timeseries_plot when multi_YoY=True * update to warning message in plotting.degradation_timeseries_plot * fix flake8 grumbles * nbval fixes from qnguyen345-bare_except_error * Add pandas 3.0 futurewarning handling * Try again to solve pandas3.0 futurewarning * attempt 3 to fix nbval * Add infer_objects to remove futurewarning * minor inline comment update * update plotting tests to be relative value, update ordering of module import in plotting.py, per Copilot review. * update inline comments and whatsnew docs * Clean up inline comments per Copilot review * added multi-YoY pytest - still need to catch warnings * Add a warnings.catch_warnings to the plotting pytest * flake8 grumbles * add multi-YoY=True pytest * updated changelog * update changelog * implement copilot suggestions * linting * use s instead of ns for pandas 3 compatibility * update pandas version comparison * set matplotlib non-gui backend for tests * set dtype resolution based on pandas version * linting import order * boost degradation.py test coverage * update changelog * exclude coverage reports with suffixes * Update rdtools/degradation.py Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * remove label=None handling, rely on default 'right' behavior * refactor dt_center tz handling for old pandas * simplify _avg_timestamp_old_Pandas * degradation_timeseries_plot: change rolling median min_periods to rolling_days / 4. * remove degradation_timeseries_plot(label=) and just default to center=True * update sensor_analysis() and clearsky_analysis() docstrings to discuss passing `label=right` kwargs * flake8 updates * Initial commit - multi-YoY notebook * pretty-print notebook dataframes with tabulate. * update notebook requirements to silence pandas warnings * add multi-yoy nb to tutorials * fix nblink path * Change the yoy_values index to be named 'dt'. Add new illustrations at the end of the multi-YoY notebook. --------- Co-authored-by: Michael Deceglie <mdeceglie@users.noreply.github.com> Co-authored-by: martin-springer <martinspringer.ms@gmail.com> Co-authored-by: Martin Springer <97482055+martin-springer@users.noreply.github.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
1 parent 6a05165 commit 0294a7e

16 files changed

+990
-47
lines changed

.github/workflows/nbval.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@ jobs:
2828
pip install --timeout=300 -r requirements.txt -r docs/notebook_requirements.txt .[test]
2929
- name: Run notebook and check output
3030
run: |
31-
# --sanitize-with: pre-process text to remove irrelevant differences (e.g. warning filepaths)
32-
pytest --nbval docs/${{ matrix.notebook-file }} --sanitize-with docs/nbval_sanitization_rules.cfg
31+
# --nbval-sanitize-with: pre-process text to remove irrelevant differences (e.g. warning filepaths)
32+
pytest --nbval --nbval-sanitize-with docs/nbval_sanitization_rules.cfg docs/${{ matrix.notebook-file }}
3333
- name: Run notebooks again, save files
3434
run: |
3535
pip install nbconvert[webpdf]

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,10 @@
77
# ignore byte compiled files
88
*.py[co]
99

10-
# ignore coveralls yaml, coverge dir
10+
# ignore coveralls yaml, coverage dir
1111
.coveralls.yml
1212
.coverage
13+
.coverage.*
1314
htmlcov/
1415

1516
# ignore test cache

docs/Multi-year_on_year_example.ipynb

Lines changed: 479 additions & 0 deletions
Large diffs are not rendered by default.

docs/TrendAnalysis_example.ipynb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62377,7 +62377,7 @@
6237762377
"# Visualize the results\n",
6237862378
"ta_new_filter.plot_degradation_summary('sensor', summary_title='Sensor-based degradation results',\n",
6237962379
" scatter_ymin=0.5, scatter_ymax=1.1,\n",
62380-
" hist_xmin=-30, hist_xmax=45);\n",
62380+
" hist_xmin=-30, hist_xmax=45)\n",
6238162381
"plt.show()"
6238262382
]
6238362383
},
@@ -62492,7 +62492,7 @@
6249262492
"# Visualize the results\n",
6249362493
"ta_stuck_filter.plot_degradation_summary('sensor', summary_title='Sensor-based degradation results',\n",
6249462494
" scatter_ymin=0.5, scatter_ymax=1.1,\n",
62495-
" hist_xmin=-30, hist_xmax=45);\n",
62495+
" hist_xmin=-30, hist_xmax=45)\n",
6249662496
"plt.show()"
6249762497
]
6249862498
},

docs/TrendAnalysis_example_NSRDB.ipynb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@
200200
"ax.plot(df.index, df.soiling, 'o', alpha=0.01)\n",
201201
"#ax.set_ylim(0,1500)\n",
202202
"fig.autofmt_xdate()\n",
203-
"ax.set_ylabel('soiling signal');\n",
203+
"ax.set_ylabel('soiling signal')\n",
204204
"df['power'] = df['power_ac'] * df['soiling']\n",
205205
"\n",
206206
"plt.show()"

docs/notebook_requirements.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ nbconvert==7.17.0
3030
nbformat==5.10.4
3131
nest-asyncio==1.6.0
3232
notebook==7.2.2
33-
numexpr==2.10.1
33+
numexpr==2.10.2
3434
pandocfilters==1.5.1
3535
parso==0.8.4
3636
pexpect==4.9.0
@@ -45,6 +45,7 @@ qtconsole==5.5.2
4545
Send2Trash==1.8.3
4646
simplegeneric==0.8.1
4747
soupsieve==2.6
48+
tabulate==0.9.0
4849
terminado==0.18.1
4950
testpath==0.6.0
5051
tinycss2==1.2.1
@@ -53,3 +54,4 @@ traitlets==5.14.3
5354
wcwidth==0.2.13
5455
webencodings==0.5.1
5556
widgetsnbextension==4.0.11
57+

docs/sphinx/source/changelog.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
RdTools Change Log
22
==================
3+
.. include:: changelog/pending.rst
34
.. include:: changelog/v3.1.0.rst
45
.. include:: changelog/v3.0.1.rst
56
.. include:: changelog/v3.0.0.rst
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
*************************
2+
v3.2.0 (X, X, 2026)
3+
*************************
4+
5+
Enhancements
6+
------------
7+
* :py:func:`~rdtools.degradation.degradation_year_on_year` has new parameter ``label=``
8+
to return the calc_info['YoY_values'] as either right labeled (default), left or
9+
center labeled. (:issue:`459`)
10+
* :py:func:`~rdtools.plotting.degradation_timeseries_plot` now defaults to rolling
11+
median, centered on the timestamp (pd.rolling(center=True)).
12+
(:issue:`455`)
13+
* :py:func:`~rdtools.degradation.degradation_year_on_year` has new parameter ``multi_yoy``
14+
(default False) to trigger multiple YoY degradation calculations similar to Hugo Quest et
15+
al 2023. In this mode, instead of a series of 1-year duration slopes, 2-year, 3-year etc
16+
slopes are also included. calc_info['YoY_values'] returns a non-monotonic index
17+
in this mode due to multiple overlapping annual slopes. (:issue:`394`)
18+
* :py:func:`~rdtools.plotting.degradation_timeseries_plot` now supports ``multi_yoy=True``
19+
data by resampling overlapping YoY values to their mean. A warning is issued when this
20+
resampling occurs. (:issue:`394`)
21+
* :py:func:`~rdtools.plotting.degradation_summary_plots` ``detailed=True`` mode now
22+
properly handles points used odd vs even number of times (not just 0, 1, 2).
23+
(:issue:`394`)
24+
* :py:func:`~rdtools.degradation.degradation_year_on_year` now returns
25+
``calc_info['YoY_times']`` DataFrame with ``dt_right``, ``dt_center``, and ``dt_left``
26+
columns for each YoY slope. (:issue:`459`)
27+
* Added new example notebook ``docs/Multi-year_on_year_example.ipynb`` demonstrating the
28+
``label='center'`` and ``multi_yoy=True`` features of
29+
:py:func:`~rdtools.degradation.degradation_year_on_year`. (:issue:`394`)
30+
31+
Bug Fixes
32+
---------
33+
* Fixed ``usage_of_points`` calculation in :py:func:`~rdtools.degradation.degradation_year_on_year`
34+
to properly handle ``multi_yoy=True`` mode with overlapping slopes. (:issue:`394`)
35+
36+
37+
Maintenance
38+
-----------
39+
* Added ``_avg_timestamp_old_Pandas`` helper function for pandas <2.0 compatibility
40+
when calculating center labels.
41+
* Fixed nbval workflow command syntax (``--sanitize-with`` to ``--nbval-sanitize-with``).
42+
* Improved pandas 3.0 compatibility with datetime resolution handling.
43+
* Updated ``docs/notebook_requirements.txt`` to require ``numexpr>=2.10.2`` and
44+
``tabulate>=0.9.0`` to satisfy pandas' optional dependency minimum versions and
45+
avoid related warnings/errors.
46+
47+
Testing
48+
-------
49+
* Added tests for error handling paths in :py:mod:`~rdtools.degradation`:
50+
``classical_decomposition`` missing/irregular data, ``year_on_year`` circular block
51+
validation, no valid pairs error, and ``_mk_test`` edge cases (no trend, ties,
52+
decreasing).
53+
* Added test for ``multi_yoy=True`` parameter in ``degradation_year_on_year``.
54+
* Set matplotlib backend to ``Agg`` in test ``conftest.py`` to avoid tkinter issues.
55+
56+
57+
Contributors
58+
------------
59+
* Chris Deline (:ghuser:`cdeline`)
60+
* Martin Springer (:ghuser:`martin-springer`)
61+

docs/sphinx/source/examples.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,4 @@ This page shows example usage of the RdTools analysis functions.
2626
examples/TrendAnalysis_example
2727
examples/TrendAnalysis_example_NSRDB
2828
examples/system_availability_example
29+
examples/Multi-year_on_year_example
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"path": "../../../Multi-year_on_year_example.ipynb"
3+
}

0 commit comments

Comments
 (0)