Skip to content

Commit

Permalink
Merge pull request #115 from pybop-team/114-plotting-classes
Browse files Browse the repository at this point in the history
Adds plotting methods
  • Loading branch information
BradyPlanden authored Dec 1, 2023
2 parents 5225cfc + 1e505ee commit 96b1ffb
Show file tree
Hide file tree
Showing 27 changed files with 966 additions and 156 deletions.
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
# [Unreleased](https://github.com/pybop-team/PyBOP)

## Features
- [#114](https://github.com/pybop-team/PyBOP/issues/114) - Adds standard plotting class `pybop.StandardPlot()` via plotly backend
- [#114](https://github.com/pybop-team/PyBOP/issues/114) - Adds `quick_plot()`, `plot_convergence()`, and `plot_cost2d()` methods
- [#116](https://github.com/pybop-team/PyBOP/issues/116) - Adds PSO, SNES, XNES, ADAM, and IPropMin optimisers to PintsOptimisers() class

## Bug Fixes

# [v23.11](https://github.com/pybop-team/PyBOP/releases/tag/v23.11)
- Initial release
- Adds Pints, NLOpt, and SciPy optimisers
Expand Down
17 changes: 15 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,20 @@
# Contributing to PyBOP

If you'd like to contribute to PyBOP, please have a look at the [pre-commit](#pre-commit-checks) and the [workflow](#workflow) guidelines below.
If you'd like to contribute to PyBOP, please have a look at the guidelines below.

## Installation

To install PyBOP for development purposes, which includes the testing and plotting dependencies, use the `[all]` flag as demonstrated below:

For `zsh`:

```sh
pip install -e '.[all]'
```
For `bash`:
```sh
pip install -e .[all]
```
## Pre-commit checks

Before you commit any code, please perform the following checks:
Expand Down Expand Up @@ -123,7 +136,7 @@ If you have nox installed, to run unit tests, type
nox -s unit
```

else, type
Alternatively, to run tests standalone with pytest, run,

```bash
pytest --unit -v
Expand Down
6 changes: 1 addition & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,11 +71,7 @@ To alternatively install PyBOP from a local directory, use the following templat
pip install -e "path/to/pybop"
```

To check whether PyBOP has been installed correctly, run one of the examples in the following section or the full set of unit tests:

```bash
pytest --unit -v
```
To check whether PyBOP has been installed correctly, run one of the examples in the following section. For a development installation, please refer to the [contributing guide](https://github.com/pybop-team/PyBOP/blob/develop/CONTRIBUTING.md#Installation).

### Prerequisites
To use and/or contribute to PyBOP, first install Python (3.8-3.11). On a Debian-based distribution, this looks like:
Expand Down
34 changes: 21 additions & 13 deletions conftest.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import pytest
import matplotlib
import plotly

plotly.io.renderers.default = None
matplotlib.use("Template")


Expand All @@ -13,24 +15,30 @@ def pytest_addoption(parser):
)


def pytest_terminal_summary(terminalreporter, exitstatus, config):
"""Add additional section to terminal summary reporting."""
total_time = sum([x.duration for x in terminalreporter.stats.get("passed", [])])
num_tests = len(terminalreporter.stats.get("passed", []))
print(f"\nTotal number of tests completed: {num_tests}")
print(f"Total time taken: {total_time:.2f} seconds")


def pytest_configure(config):
config.addinivalue_line("markers", "unit: mark test as a unit test")
config.addinivalue_line("markers", "examples: mark test as an example")


def pytest_collection_modifyitems(config, items):
def skip_marker(marker_name, reason):
skip = pytest.mark.skip(reason=reason)
if config.getoption("--unit") and not config.getoption("--examples"):
skip_examples = pytest.mark.skip(
reason="need --examples option to run examples tests"
)
for item in items:
if marker_name in item.keywords:
item.add_marker(skip)

if config.getoption("--unit"):
skip_marker("examples", "need --examples option to run")
return
if "examples" in item.keywords:
item.add_marker(skip_examples)

if config.getoption("--examples"):
skip_marker("unit", "need --unit option to run")
return

skip_marker("unit", "need --unit option to run")
if config.getoption("--examples") and not config.getoption("--unit"):
skip_unit = pytest.mark.skip(reason="need --unit option to run unit tests")
for item in items:
if "unit" in item.keywords:
item.add_marker(skip_unit)
32 changes: 19 additions & 13 deletions examples/scripts/spm_CMAES.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import pybop
import numpy as np
import matplotlib.pyplot as plt

# Define model
parameter_set = pybop.ParameterSet("pybamm", "Chen2020")
model = pybop.lithium_ion.SPM(parameter_set=parameter_set)

Expand All @@ -19,13 +19,15 @@
),
]

# Generate data
sigma = 0.001
t_eval = np.arange(0, 900, 2)
values = model.predict(t_eval=t_eval)
CorruptValues = values["Terminal voltage [V]"].data + np.random.normal(
0, sigma, len(t_eval)
)

# Form dataset for optimisation
dataset = [
pybop.Dataset("Time [s]", t_eval),
pybop.Dataset("Current function [A]", values["Current [A]"].data),
Expand All @@ -38,18 +40,22 @@
optim = pybop.Optimisation(cost, optimiser=pybop.CMAES)
optim.set_max_iterations(100)

# Run the optimisation
x, final_cost = optim.run()
print("Estimated parameters:", x)

# Show the generated data
simulated_values = problem.evaluate(x)

plt.figure(dpi=100)
plt.xlabel("Time", fontsize=12)
plt.ylabel("Values", fontsize=12)
plt.plot(t_eval, CorruptValues, label="Measured")
plt.fill_between(t_eval, simulated_values - sigma, simulated_values + sigma, alpha=0.2)
plt.plot(t_eval, simulated_values, label="Simulated")
plt.legend(bbox_to_anchor=(0.6, 1), loc="upper left", fontsize=12)
plt.tick_params(axis="both", labelsize=12)
plt.show()
# Plot the timeseries output
pybop.quick_plot(x, cost, title="Optimised Comparison")

# Plot convergence
pybop.plot_convergence(optim)

# Plot the parameter traces
pybop.plot_parameters(optim)

# Plot the cost landscape
pybop.plot_cost2d(cost, steps=15)

# Plot the cost landscape with optimisation path and updated bounds
bounds = np.array([[0.6, 0.9], [0.5, 0.8]])
pybop.plot_cost2d(cost, optim=optim, bounds=bounds, steps=15)
28 changes: 15 additions & 13 deletions examples/scripts/spm_IRPropMin.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import pybop
import numpy as np
import matplotlib.pyplot as plt

# Define model
parameter_set = pybop.ParameterSet("pybamm", "Chen2020")
model = pybop.lithium_ion.SPM(parameter_set=parameter_set)

Expand Down Expand Up @@ -41,15 +41,17 @@
x, final_cost = optim.run()
print("Estimated parameters:", x)

# Show the generated data
simulated_values = problem.evaluate(x)

plt.figure(dpi=100)
plt.xlabel("Time", fontsize=12)
plt.ylabel("Values", fontsize=12)
plt.plot(t_eval, CorruptValues, label="Measured")
plt.fill_between(t_eval, simulated_values - sigma, simulated_values + sigma, alpha=0.2)
plt.plot(t_eval, simulated_values, label="Simulated")
plt.legend(bbox_to_anchor=(0.6, 1), loc="upper left", fontsize=12)
plt.tick_params(axis="both", labelsize=12)
plt.show()
# Plot the timeseries output
pybop.quick_plot(x, cost, title="Optimised Comparison")

# Plot convergence
pybop.plot_convergence(optim)

# Plot the parameter traces
pybop.plot_parameters(optim)

# Plot the cost landscape
pybop.plot_cost2d(cost, steps=15)

# Plot the cost landscape with optimisation path
pybop.plot_cost2d(cost, optim=optim, steps=15)
28 changes: 15 additions & 13 deletions examples/scripts/spm_SNES.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import pybop
import numpy as np
import matplotlib.pyplot as plt

# Define model
parameter_set = pybop.ParameterSet("pybamm", "Chen2020")
model = pybop.lithium_ion.SPM(parameter_set=parameter_set)

Expand Down Expand Up @@ -41,15 +41,17 @@
x, final_cost = optim.run()
print("Estimated parameters:", x)

# Show the generated data
simulated_values = problem.evaluate(x)

plt.figure(dpi=100)
plt.xlabel("Time", fontsize=12)
plt.ylabel("Values", fontsize=12)
plt.plot(t_eval, CorruptValues, label="Measured")
plt.fill_between(t_eval, simulated_values - sigma, simulated_values + sigma, alpha=0.2)
plt.plot(t_eval, simulated_values, label="Simulated")
plt.legend(bbox_to_anchor=(0.6, 1), loc="upper left", fontsize=12)
plt.tick_params(axis="both", labelsize=12)
plt.show()
# Plot the timeseries output
pybop.quick_plot(x, cost, title="Optimised Comparison")

# Plot convergence
pybop.plot_convergence(optim)

# Plot the parameter traces
pybop.plot_parameters(optim)

# Plot the cost landscape
pybop.plot_cost2d(cost, steps=15)

# Plot the cost landscape with optimisation path
pybop.plot_cost2d(cost, optim=optim, steps=15)
28 changes: 15 additions & 13 deletions examples/scripts/spm_XNES.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import pybop
import numpy as np
import matplotlib.pyplot as plt

# Define model
parameter_set = pybop.ParameterSet("pybamm", "Chen2020")
model = pybop.lithium_ion.SPM(parameter_set=parameter_set)

Expand Down Expand Up @@ -41,15 +41,17 @@
x, final_cost = optim.run()
print("Estimated parameters:", x)

# Show the generated data
simulated_values = problem.evaluate(x)

plt.figure(dpi=100)
plt.xlabel("Time", fontsize=12)
plt.ylabel("Values", fontsize=12)
plt.plot(t_eval, CorruptValues, label="Measured")
plt.fill_between(t_eval, simulated_values - sigma, simulated_values + sigma, alpha=0.2)
plt.plot(t_eval, simulated_values, label="Simulated")
plt.legend(bbox_to_anchor=(0.6, 1), loc="upper left", fontsize=12)
plt.tick_params(axis="both", labelsize=12)
plt.show()
# Plot the timeseries output
pybop.quick_plot(x, cost, title="Optimised Comparison")

# Plot convergence
pybop.plot_convergence(optim)

# Plot the parameter traces
pybop.plot_parameters(optim)

# Plot the cost landscape
pybop.plot_cost2d(cost, steps=15)

# Plot the cost landscape with optimisation path
pybop.plot_cost2d(cost, optim=optim, steps=15)
27 changes: 14 additions & 13 deletions examples/scripts/spm_adam.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import pybop
import numpy as np
import matplotlib.pyplot as plt

# Parameter set and model definition
parameter_set = pybop.ParameterSet("pybamm", "Chen2020")
Expand Down Expand Up @@ -45,15 +44,17 @@
x, final_cost = optim.run()
print("Estimated parameters:", x)

# Show the generated data
simulated_values = problem.evaluate(x)

plt.figure(dpi=100)
plt.xlabel("Time", fontsize=12)
plt.ylabel("Values", fontsize=12)
plt.plot(t_eval, corrupt_values, label="Measured")
plt.fill_between(t_eval, simulated_values - sigma, simulated_values + sigma, alpha=0.2)
plt.plot(t_eval, simulated_values, label="Simulated")
plt.legend(bbox_to_anchor=(0.6, 1), loc="upper left", fontsize=12)
plt.tick_params(axis="both", labelsize=12)
plt.show()
# Plot the timeseries output
pybop.quick_plot(x, cost, title="Optimised Comparison")

# Plot convergence
pybop.plot_convergence(optim)

# Plot the parameter traces
pybop.plot_parameters(optim)

# Plot the cost landscape
pybop.plot_cost2d(cost, steps=15)

# Plot the cost landscape with optimisation path
pybop.plot_cost2d(cost, optim=optim, steps=15)
27 changes: 14 additions & 13 deletions examples/scripts/spm_descent.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import pybop
import numpy as np
import matplotlib.pyplot as plt

# Parameter set and model definition
parameter_set = pybop.ParameterSet("pybamm", "Chen2020")
Expand Down Expand Up @@ -46,15 +45,17 @@
x, final_cost = optim.run()
print("Estimated parameters:", x)

# Show the generated data
simulated_values = problem.evaluate(x)

plt.figure(dpi=100)
plt.xlabel("Time", fontsize=12)
plt.ylabel("Values", fontsize=12)
plt.plot(t_eval, corrupt_values, label="Measured")
plt.fill_between(t_eval, simulated_values - sigma, simulated_values + sigma, alpha=0.2)
plt.plot(t_eval, simulated_values, label="Simulated")
plt.legend(bbox_to_anchor=(0.6, 1), loc="upper left", fontsize=12)
plt.tick_params(axis="both", labelsize=12)
plt.show()
# Plot the timeseries output
pybop.quick_plot(x, cost, title="Optimised Comparison")

# Plot convergence
pybop.plot_convergence(optim)

# Plot the parameter traces
pybop.plot_parameters(optim)

# Plot the cost landscape
pybop.plot_cost2d(cost, steps=15)

# Plot the cost landscape with optimisation path
pybop.plot_cost2d(cost, optim=optim, steps=15)
Loading

0 comments on commit 96b1ffb

Please sign in to comment.