Skip to content
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

Added a function to plot "summary variables" #1678

Merged
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

## Features

- Added `plot_summary_variables` to plot and compare summary variables ([#1678](https://github.com/pybamm-team/PyBaMM/pull/1678))
- The DFN model can now be used directly (instead of `BasicDFNHalfCell`) to simulate a half-cell ([#1600](https://github.com/pybamm-team/PyBaMM/pull/1600))

## Breaking changes
Expand Down
1 change: 1 addition & 0 deletions docs/source/plotting/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ Plotting
plot
plot_2D
plot_voltage_components
plot_summary_variables
4 changes: 4 additions & 0 deletions docs/source/plotting/plot_summary_variables.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Plot Summary Variables
======================

.. autofunction:: pybamm.plot_summary_variables
2,871 changes: 1,750 additions & 1,121 deletions examples/notebooks/simulating-long-experiments.ipynb

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions pybamm/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,7 @@ def version(formatted=False):
from .plotting.plot import plot
from .plotting.plot2D import plot2D
from .plotting.plot_voltage_components import plot_voltage_components
from .plotting.plot_summary_variables import plot_summary_variables
from .plotting.dynamic_plot import dynamic_plot

#
Expand Down
79 changes: 79 additions & 0 deletions pybamm/plotting/plot_summary_variables.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
#
# Method for plotting/comparing summary variables
#
import numpy as np
import pybamm


def plot_summary_variables(
solutions, output_variables=None, labels=None, testing=False, **kwargs_fig
):
"""
Generate a plot showing/comparing the summary variables.

Parameters
----------
solutions : (iter of) :class:`pybamm.Solution`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can this be made to work if only a single solution is provided not in a list, e.g.

if isinstance(solutions, pybamm.Solution):
    solutions = [solutions]

The solution(s) for the model(s) from which to extract summary variables.
output_variables: list (optional)
A list of variables to plot automatically. If None, the default ones are used.
labels: list (optional)
A list of labels to be added to the legend. No labels are added by default.
testing : bool (optional)
Whether to actually make the plot (turned off for unit tests).
kwargs_fig
Keyword arguments, passed to plt.subplots.

"""
import matplotlib.pyplot as plt

if isinstance(solutions, pybamm.Solution):
solutions = [solutions]

# setting a default value for figsize
kwargs_fig = {"figsize": (15, 8), **kwargs_fig}

if output_variables is None:
output_variables = [
"Capacity [A.h]",
"Loss of lithium inventory [%]",
"Loss of capacity to SEI [A.h]",
"Loss of active material in negative electrode [%]",
"Loss of active material in positive electrode [%]",
"x_100",
"x_0",
"y_100",
"y_0",
]

# find the number of subplots to be created
length = len(output_variables)
n = int(length // np.sqrt(length))
m = int(np.ceil(length / n))

# create subplots
fig, axes = plt.subplots(n, m, **kwargs_fig)

# loop through the subplots and plot the output_variables
for var, ax in zip(output_variables, axes.flat):
# loop through the solutions to compare output_variables
for solution in solutions:
# plot summary variable v/s cycle number
ax.plot(
solution.summary_variables["Cycle number"],
solution.summary_variables[var],
)
# label the axes
ax.set_xlabel("Cycle number")
ax.set_ylabel(var)
ax.set_xlim([1, solution.summary_variables["Cycle number"][-1]])

fig.tight_layout()

# add labels in legend
if labels is not None: # pragma: no cover
fig.legend(labels, loc="lower right")
if not testing: # pragma: no cover
plt.show()

return axes
86 changes: 86 additions & 0 deletions tests/unit/test_plotting/test_plot_summary_variables.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import pybamm
import unittest
import numpy as np


class TestPlotSummaryVariables(unittest.TestCase):
def test_plot(self):
model = pybamm.lithium_ion.SPM({"SEI": "ec reaction limited"})
parameter_values = pybamm.ParameterValues(
chemistry=pybamm.parameter_sets.Mohtat2020
)
experiment = pybamm.Experiment(
[
(
"Discharge at C/10 for 10 hours or until 3.3 V",
"Rest for 1 hour",
"Charge at 1 A until 4.1 V",
"Hold at 4.1 V until 50 mA",
"Rest for 1 hour",
)
]
* 3,
)
output_variables = [
"Capacity [A.h]",
"Loss of lithium inventory [%]",
"Loss of capacity to SEI [A.h]",
"Loss of active material in negative electrode [%]",
"Loss of active material in positive electrode [%]",
"x_100",
"x_0",
"y_100",
"y_0",
]
sim = pybamm.Simulation(
model, experiment=experiment, parameter_values=parameter_values
)
sol = sim.solve(initial_soc=1)

axes = pybamm.plot_summary_variables(sol, testing=True)

axes = axes.flatten()
self.assertEqual(len(axes), 9)

for output_var, ax in zip(output_variables, axes):
self.assertEqual(ax.get_xlabel(), "Cycle number")
self.assertEqual(ax.get_ylabel(), output_var)

cycle_number, var = ax.get_lines()[0].get_data()
np.testing.assert_array_equal(
cycle_number, sol.summary_variables["Cycle number"]
)
np.testing.assert_array_equal(var, sol.summary_variables[output_var])

axes = pybamm.plot_summary_variables(
[sol, sol], labels=["SPM", "SPM"], testing=True
)

axes = axes.flatten()
self.assertEqual(len(axes), 9)

for output_var, ax in zip(output_variables, axes):
self.assertEqual(ax.get_xlabel(), "Cycle number")
self.assertEqual(ax.get_ylabel(), output_var)

cycle_number, var = ax.get_lines()[0].get_data()
np.testing.assert_array_equal(
cycle_number, sol.summary_variables["Cycle number"]
)
np.testing.assert_array_equal(var, sol.summary_variables[output_var])

cycle_number, var = ax.get_lines()[1].get_data()
np.testing.assert_array_equal(
cycle_number, sol.summary_variables["Cycle number"]
)
np.testing.assert_array_equal(var, sol.summary_variables[output_var])


if __name__ == "__main__":
print("Add -v for more debug output")
import sys

if "-v" in sys.argv:
debug = True
pybamm.settings.debug_mode = True
unittest.main()