Exercises: Modularisation
Use this notebook for the practical tasks.
Before starting, ensure plot_example.py is open side-by-side with this notebook.
Setup
Important when editing modules
If you change plot_example.py while this notebook is open, you must refresh what the notebook sees.
importlib is a standard Python library module for working with imports programmatically.
importlib.reload(module_name) tells Python to re-read that module file from disk and replace the in-memory version.
You can either restart and run all cells, or reload the module in-place:
import importlib
import plot_example
importlib.reload(plot_example)Use reload whenever you edit functions in plot_example.py and want those edits to be used immediately in this notebook session.
Exercise 1
Learning goal: implement a missing function in a module and call it from a notebook.
In plot_example.py, find the plot_uncert() function stub (currently with pass).
Use this code inside plot_uncert():
# Define upper and lower bounds of shading using the error term
y_low = y - yerr
y_high = y + yerr
# Plot the line and the shading around it
ax.plot(x, y)
ax.fill_between(x, y1=y_low, y2=y_high, alpha=0.3, label=label)
ax.legend()Steps 1) Update plot_example.py with this implementation.
Save the module, then import and run the test plot below.
If your edits do not appear, run
importlib.reload(plot_example)before testing.
Success check: your figure should show a line with a shaded uncertainty region around it.
Exercise 2
Learning goal: identify reusable vs dataset-specific code and wrap reusable parts in a function.
Steps 1) Recreate the matplotlib stackplot demo in the cell below: https://matplotlib.org/stable/gallery/lines_bars_and_markers/stackplot_demo.html
Consider which parts are generic and which are specific to one dataset.
- In
plot_example.py, use the providedplot_population_stacked()stub (or create your own more generic function). - Import your function and test it in this notebook.
Success check: your function plots a stackplot from inputs, rather than hard-coded values.
Questions - How could this function be improved? - How could it be made generic enough for any stackplot, not just year vs population? - Could the input structure be improved beyond a dictionary of lists?
Exercise 3
Learning goal: understand notebook module caching and verify that reload applies code edits.
Steps 1) In plot_example.py, modify time_scatter() so it accepts an optional marker argument (default '+') and uses that marker in ax.scatter(...). 2) Save plot_example.py, then reload the module in this notebook and test two different markers. 3) Briefly note what happened before and after reloading.
Success check: your plot displays different marker styles, and your notes explain why reload was needed.
Write 2-3 sentences: Why is reloading needed in notebooks when a module file changes?
Exercise 4
Learning goal: improve function robustness with validation and configurable parameters.
Steps 1) Update plot_population_stacked() so it checks that every population series has the same length as year. 2) If a mismatch is found, raise a ValueError with a clear message. 3) Add optional inputs legend_loc='upper left' and alpha=0.85, then use them in the plot. 4) Demonstrate one valid call and one invalid call (inside try/except) below.
Success check: the valid example plots correctly, and the invalid example raises your custom error message.
Exercise 5
Now you can create your own modularised plotting function. The problem you want to solve is to take input data in x and y sequences and construct a funciton that plots the data together with an arbitrary polynomial fit of specified degree. You can use numpy.polyfit() to compute the polynomial coefficients and numpy.polyval() to create a polynomial function that can be evaluated at any x value.
Steps
- Write the function in the notebook first, and experiment a bit
- Move the function to
plot_example.pyand test it in this notebook. - Make sure that you have added suitable error handling to your function, and test that it works by calling the function with wrong inputs.
- Make sure that you have added a docstring to your function, and test that it is informative and clear by calling
help(your_function_name).
Success check Test the function with some synthetic data.
Then test it again with a real dataset, by taking the UK time series from the Energy per person dataset from Our World in Data here below.