Figure Laboratory with Matplotlib

Week 9 · 2105620 · Python for first-time users · 09:00–12:00

Soorathep Kheawhom

15 October 2026

Today’s deliverables

  • A two-panel figure with units and defined SD bars
  • A 40–70-word caption that matches the plotted data
  • A notebook that recreates the figure after a restart

Today’s routine: predict a change, run the cell, check the result.

Notebook basics

  • A code cell runs Python. A Markdown cell explains it.
  • Shift + Enter runs a cell. The Run button also works.
  • The kernel keeps values in memory until you restart it.
  • Run code cells from top to bottom. Wait for each to finish.

Code cell 1: setup. Code cell 2: variables and lists.

First run

  1. Unzip the lab materials into one folder.
  2. Open week09_starter.ipynb in the prepared Jupyter environment.
  3. Keep the CSV and skh_palette.py beside the notebook.
  4. Run code cell 1. Look for Setup complete.

If setup is still blocked at 09:15: work with a partner and use the instructor’s running notebook.

A variable stores a value

temperature_C = 300
conversion_pct = 40
print(temperature_C, conversion_pct)

Expected output: 300 40

Change temperature_C to 325. Predict, run, then check.

The names record our intended units. Python stores the numbers.

Lists preserve the pairing of values

temperature = [300, 325, 350, 375]
conversion = [40, 55, 70, 80]
print(len(temperature), len(conversion))

Expected output: 4 4

Pair by position: 300 °C with 40%, then 325 °C with 55%.

Code cell 2: each x value needs a matching y value.

Functions and named arguments

fig, ax = plt.subplots()
ax.plot(temperature, conversion,
        marker="o", linewidth=1.8,
        color=skh.C["amber"])
plt.show()

fig: the whole figure. ax: one plotting area.

plot(...) draws data. Named arguments set its appearance.

After code cells 1–2: try marker="s". Check what changes.

Errors are clues

Message First check
NameError Correct spelling? Definition cell already run?
FileNotFoundError CSV beside notebook? Exact filename?
KeyError Column name matches df.columns?
SyntaxError Quotes, commas and brackets complete?

Read the last error line, then the line it points to.

Reading a CSV file

df = pd.read_csv("synthetic_reaction_runs.csv")
display(df.head())
print(df.columns.tolist())
print(df.groupby("temperature_C").size())

Code cell 3: setup already imports pandas as pd.

Check: 12 rows, 4 temperatures, 3 independent runs each.

The structure of the teaching data

temperature_C run conversion_pct selectivity_pct
300 1 38 91
300 2 40 90
300 3 42 89

One row = one independent simulated run at fixed residence time, 2.0 s.

First 3 of 12 rows. Conversion and selectivity in the same row belong to the same run.

The first scatter plot

fig, ax = plt.subplots()
ax.scatter(df["temperature_C"],
           df["conversion_pct"],
           color=skh.C["amber"], s=36)
plt.show()

Code cell 4: brackets select a column. Each point is one run.

Try s=64. Marker area changes. The data stay fixed.

Labels state the quantity and unit

ax.set_xlabel("Temperature (°C)")
ax.set_ylabel("Conversion (%)")
ax.set_ylim(0, 100)
ax.set_xticks([300, 325, 350, 375])

In code cell 4, keep these lines before plt.show().

Run the whole cell again. Check quantity, unit and tick positions.

Checkpoint before the break

  • The figure contains 12 runs at four temperatures.
  • The axes show Temperature (°C) and Conversion (%).
  • Both list variables still contain four entries.
  • Explain one changed line and its visible effect to a partner.

If the plot fails, read the first failing cell with your partner.

Break

15 minutes

Resume at 10:30

The summary should match the original data

summary = df.groupby("temperature_C").agg(
    mean_X=("conversion_pct", "mean"),
    sd_X=("conversion_pct", "std"),
    mean_S=("selectivity_pct", "mean"),
    sd_S=("selectivity_pct", "std")
)

Code cell 5, at 300 °C: X = 40 ± 2%, S = 90 ± 1% (mean ± SD).

Three runs per temperature. Sample SD uses n − 1.

Error bars show a defined quantity

fig, ax = plt.subplots()
ax.errorbar(summary.index, summary["mean_X"],
            yerr=summary["sd_X"], fmt="o-",
            color=skh.C["amber"], capsize=4,
            linewidth=1.8, markersize=5)

Four means and four SDs in the same temperature order.

yerr gives nonnegative distances from each mean. At 300 °C: 38–42%.

The summary still needs a caption

  • Points: mean conversion at each temperature
  • Bars: ±1 sample SD across independent simulated runs
  • Sample size: n = 3 per temperature
  • Fixed residence time: 2.0 s
  • Data status: synthetic, for teaching

A reader should understand the figure without opening the code.

Two panels share one temperature scale

fig, axes = plt.subplots(
    1, 2, figsize=(9, 3.8),
    sharex=True, layout="constrained"
)
# axes[0]: conversion, left panel
# axes[1]: selectivity, right panel

Code cell 6: one figure, two plotting areas.

Each panel needs its own response label and matching SD column.

Color and symbols carry meaning

  • Amber marks the response being studied.
  • Teal represents a control or reference when one exists.
  • Both response panels use amber and distinct axis labels.
  • Symbols and labels preserve meaning in grayscale.

A color change needs a reason the reader can understand.

The expected figure

Conversion rises from 40% to 80%, while selectivity falls from 90% to 65%. Error bars show sample SD.

Synthetic data at 2.0 s. Means ±1 sample SD, n = 3 per temperature. The CSV and this figure use the same runs.

Figure workshop

30 min

  1. 20 min: run both panels. Verify values, units and SD bars.
  2. 10 min: write a 40–70-word caption with residence time and n.
  3. Keep one design change you can explain. Save the notebook.

If blocked: pair up, use the supplied plotting cell, and annotate what each line does.

Figure review in pairs

10 min

  1. 3 min: read your partner’s figure. State its main finding.
  2. 4 min: check units, n, SD definition and caption agreement.
  3. 3 min: make one specific correction and explain its benefit.

Feedback example: “Add ‘±1 sample SD, n = 3’ to define the bars.”

Export from the figure object

fig.savefig("reaction_figure.pdf",
            bbox_inches="tight")
fig.savefig("reaction_figure.png",
            dpi=600, bbox_inches="tight")

Code cell 7: run just after the two-panel cell. fig must refer to it.

Open both saved files. Check labels and bars at the intended size.

A reproducibility check

  1. Save the notebook, including your caption.
  2. Restart the kernel, then run all cells from the top.
  3. Confirm that both figure files appear again.
  4. Submit the notebook, CSV, palette file, figure and caption.

If a cell fails, fix that first error before checking later cells.

Exit ticket

4 min

  1. Show the figure recreated after a kernel restart.
  2. Explain what yerr contains and which runs produced it.
  3. Justify one design choice in a sentence.

Evidence to keep: your notebook, exported figure and caption.

Documentation for later use

Gallery: six figures with runnable examples

Start with one example. Change a single element and check its effect.

How was today?

Before you leave

Identify one point that is still unclear.

Name one change you will make in your writing or figure.

Complete the short anonymous feedback form.

QR code linking to the existing weekly feedback form