Skip to content

Plot Refactoring #263

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 16 commits into
base: v0.8.0-candidate
Choose a base branch
from

Conversation

pabloitu
Copy link
Collaborator

@pabloitu pabloitu commented Aug 20, 2024

closes #260
closes #258

pyCSEP Pull Request Checklist

Please check out the contributing guidelines for some tips
on making pull requests to pyCSEP.

Fixes issue #(please fill in or delete if not needed).

Type of change:

Please delete options that are not relevant.

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update

Checklist:

  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes

@pabloitu pabloitu marked this pull request as draft August 20, 2024 02:40
@pabloitu
Copy link
Collaborator Author

rasterio is breaking the macos python 3.9 CI build for some reason. Need to fix

@pabloitu
Copy link
Collaborator Author

pabloitu commented Aug 30, 2024

The refactoring is ready. All the tasks done for this refactoring are explicit in #260. Would be great if @mherrmann3, @bayonato89 and/or @Serra314 can also take a look. The main changes are:

  1. Clearly defined main and helper plotting functions, as well as removed unused functions (need feedback that im not removing something used)
  2. Harmonized function signatures (e.g., args/opt_args/kwargs):
    2.1 All the plot functions now have identically named arguments
    2.2 Removed the plot_args dictionary as argument, in favor of using direct keyword arguments (to be consistent with matplotlib and seaborn).
    2.3. Cleaned all function signatures for only those arguments that are essential for a function. Fine-tuning args (e.g. title_fontsize, legend_title) are now part of optional kwargs, and described in the docstrings.
    2.4. The plots.py module has a DEFAULT_PLOT_ARGS dictionary (similarly to matplotlib.rcParams), that contains the default values for all plotting. Any arg/kwarg passed to a function, replaced the defaults. I opted by this simple solution, but if required, we can refactor in the future to a PlotConfig class, in the plotly style.
  3. Added type hinting (e.g., plot_catalog(catalog: CSEPCatalog) ) for all the functions, so there is awareness of the argument type that a function requires.
  4. Refactored all plot_{catalogforecast_test} (e.g., number_test, spatial_test, likelihood_test) onto one function (plot_distribution_test, please advice for a more precise name), since the logic was identical. It now calls a helper function that automatically retrieves the annotations and labels for each test (e.g., spatial_test, number_test).
  5. Revamped plot_cumulative_number_versus_time and plot_magnitude_versus_time: They now use datetime for the x label, and the latter sizes the events by their magnitude (for the good looks)
  6. Added unit tests for all the plotting functions.
  7. Basemaps now caches downloaded data, so it becomes 1000% quicker to plot multiple catalogs/forecasts. Also a geotiff file can be used as basemap, as long as it is in the same projection required.
  8. The test_plots.py module, has a flag show_plots. If set to True, you can test the plots and see all the possible plots (with simple data) that pycsep can make.

This PR should go to a v1.0.0 candidate branch, since its not backwards compatible.

@pabloitu
Copy link
Collaborator Author

Suggest updating with a Plot section in the documentation, to show the plotting capabilities in a standalone section.

@pabloitu pabloitu force-pushed the 260-plot-refactoring branch from 64cca36 to b896b19 Compare April 4, 2025 13:03
@pabloitu pabloitu closed this Apr 8, 2025
@pabloitu pabloitu deleted the 260-plot-refactoring branch April 8, 2025 16:09
@pabloitu pabloitu restored the 260-plot-refactoring branch April 8, 2025 16:11
@pabloitu pabloitu reopened this Apr 8, 2025
@pabloitu pabloitu force-pushed the 260-plot-refactoring branch 2 times, most recently from c4d737d to 8578c4f Compare April 13, 2025 21:00
 - Harmonized the parameters for all plotting functions. Removed the `plot_args` argument from all functions. Now, default parameters, such as `title`, `figsize` and many other repeating parameters are now found in a global dictionary `DEFAULT_PLOT_ARGS`. All plotting functions now default to these parameters and update a copy of it with **kwargs, thus having control to customize plots. Relevant parameters to the function are left in the function signature.
 - Added type hints for all signatures.
 - Removed functions `plot_cumulative_events_versus_time_dev`, `plot_ecdf`, `plot_magnitude_histogram_dev`.
 - Refactored catalog evaluation plot functions `plot_number_test`, `plot_magnitude_test`, `plot_spatial_test`, `plot_likelihood_test` into a generic `plot_distribution_test` (Should it be renamed plot_consistency_test?). Automatic annotations for each type test are done if required, or when called directly from EvaluationResult subclasses.
 - The function `plot_poisson_consistency_test` was collapsed onto `plot_consistency_test`, which also included the negative binomial model.
 - Reworked `plot_magnitude_vs_time`: removed some old functionality and give the possibility to scale the size of each event by its magnitude. Added datetime formatter/locator
 - Reworked`plot_cumulative_events_versus_time`. Now it has the option to plot with the real datetimes, or hours/days after a given mainshock.
 - Now plot_magnitude_histogram plots in log scale.
 - plot_basemap now allows cacheing of downloaded data
 - Created or refactored from existing functions multiple helper functions to ease unit testing and code readability: `_get_basemap`,`_autosize_scatter`, `_size_map`, `_autoscale_histogram`, `_annotate_distribution_plot`, `_calculate_spatial_extent`, `_create_geo_axes`, `_calculate_marker_size`, `_add_gridlines`, `_define_colormap_and_alpha`, `_add_colorbar`, _process_stat_distribution`. These still needs some review, type hinting and further refactoring if necessary.
 tests: Completed test coverage of almost all plots.py functions. Added test artifacts for catalog based evaluations (catalogs, forecasts, test results).
…he same projection of the cartopy GeoAxes.

ft: Added cache handler for plot_basemap. Uses the cache option from cartopy, but removes the cache if a different basemap source is selected (otherwise it would get stuck with the first cached map).
tests: added .tif basemap plotting to existing unit tests
build: added rasterio as requirement
…ent into the EvaluationResult, as part of the test_distribution attribute: ('negbinom', mean, variance). plot_consistency_test() now does not accept variance as attribute, but it is rather obtained when processing the negative binomial distribution.

tests: unittests of consistency test now do not accept variance argument, and negative_binomial mocks contain the second variance parameter as part of the test_distribution
…t is not necessary to set it again when plotting. plot_comparison_test() includes a default legend that explains the symbology therein.
…em compatible with sphinx docs. Reordered the index of the API reference docs for plotting functions. Also added EvaluationResult and CartesianGrid2D.get_cartesian, which are referenced by the plot docs. Added cartopy for intersphinx_mapping

refac: Renamed plot_spatial_dataset to plot_gridded_dataset (since catalogs are also a spatial datasets)
…of plot_args. Kept the `plot_args` for legacy compatibility.

docs: Adapted tutorials to the new plot refactoring. Added catalog_plot to Catalog Operations tutorial.
ft: Added higher resolutions for basemap autoscale functions, in case extent is lower.
…ctions that would otherwise be broke with proposed changes. Deprecation strategy were issued for distinct cases:

 - Functions to be removed (plot_cumulative_events_versus_time_dev, plot_histogram, plot_ecdf, plot_magnitude_histogram_dev, add_labels_for_publication) fallback to legacy code and issue warning of future removal.
 - Abstracted functions ( [plot_number_test, plot_spatial_test, plot_magnitude_test, plot_likelihood_test] >> plot_test_distribution ;  plot_poisson_consistency_test >> plot_consistency test ) also fallback to legacy code and issue deprecation warning hinting the new function and docs.
 - Refactored functions with strong API breaks (plot_cumulative_events_versus_time, plot_basemap, plot_consistency_test (when NB-distributed)) adapts to new call with known cases OR fallsback to legacy code.
  - Refactored functions with minor API breaks (plot_comparison_test, plot_concentration_ROC_diagram, plot_ROC_diagram, plot_Molchan_diagram) only adapts to new code with known cases without fallback to legacy.
  - Renamed function (plot_spatial_dataset >> plot_gridded_dataset) just wraps to correct function.

refac: renamed plot_distribution_test to plot_test_distribution.  Added to all catalog-based-test's names the prefix "Catalog" for consistency.
ft: Added 'reset_times' to plot_magnitude_versus_time for backwards compat.
tests: added unit tests for plot_magnitude_versus_time includint reset_times arg.
…rgs is passed as arguments. Backtracked on plot_spatial_dataset, which now fallbacks to legacy call + deprecwarning.
…ing 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.
docs: Added "plot composition" section to  Plotting tutorial. Added plot_magnitude_vs_time and plot_magnitude_histogram examples to Catalog-forecast tutorial. Added reflinks to tutorial headers. Added load_evaluation_result to API ref.
ft: Added default plot_region=True to forecast.plot(). Added log_scale option to plot_magnitude_histogram for y axis, and also the mean is plotted now instead of median. Remove tight_layout from plot_catalog() option.
fix: added transform argument when plotting the region in plot_gridded_dataset.
ft: added helper to issue deprecation warning when plot_args is passed. Added typehinting overload to legacy wrappers, so IDEs can detect signature/docstrings.
fix: avoid drawing basemap when an ax is passed to plot_catalog and plot_gridded_dataset.  modified .plot methods to be consistent with new plot functionality
docs: remove plots.rst
…plot legend option to plot_consistency() to explain its symbology. Abstracted draw_shaded_bars from plot_consistency and plot_comparison test. Plot_consistency defaults to plot name of the first EvaluationResult.
@pabloitu pabloitu force-pushed the 260-plot-refactoring branch from 8578c4f to dd34480 Compare April 13, 2025 21:01
@pabloitu pabloitu changed the base branch from v1.0.0-candidate to v0.8.0-candidate April 13, 2025 21:02
…tring to where the function is used in the tutorials. Added and fixed multiple docs references. Added changelogs in docstrings with versionchanged/versionadded directives to outline major changes. Added optional label to multiple args in docstrings

ft: re-added xlabel_rotation for comparison_plots
fix: typos in docstrings
build-sphinx: rewrite "make clean" directive, to effectively delete generated sphinx-gallery and sphinx-autodocs material.
@pabloitu pabloitu force-pushed the 260-plot-refactoring branch from dd34480 to 9888bcf Compare April 13, 2025 21:44
@mherrmann3
Copy link
Contributor

mherrmann3 commented Apr 14, 2025

Great job, @pabloitu!

I think a good (and useful) test would be pyCSEP's original reproducibility package.
In so doing, it can also be adapted for compatibility with future versions of pyCSEP. Well, this would defeat the purpose reproducibility 😅

I could have a look, but cannot guarantee when I can give you feedback.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
2 participants