Exerciseschevron_rightChapter 5chevron_right5.5
fitness_center

Exercise 5.5

Multi-Well Production Overlay

Level 2
Chapter 5: Data Visualization & Plotting
descriptionProblem

Plot 36 months of oil-rate history for five wells on a single chart so the production engineer can compare them at a glance.

The starter provides a pandas DataFrame df with one row per (well, month). Five wells: OD-001, OD-003, OD-005, OD-007, OD-008, each with its own exponential decline.

Build the plot:

  1. Use a single ax (no subplots).
  2. One line per well: five lines total.
  3. Each line gets a label so the legend identifies the wells.
  4. Add x-label ("Month"), y-label ("Oil rate (bopd)"), title, legend,

and a light grid.

lightbulbHints (0/2)

Stuck? Reveal hints one at a time — they progress from nudge to near-solution.

codeYour solution
main.py
visibilityReveal reference solutionexpand_more

Try solving it yourself first — the hints walk you through it. The solution below is one valid approach; yours may differ and still be correct.

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

np.random.seed(11)
months = np.arange(0, 36)
wells_meta = [
    ("OD-001", 1500, 0.04),
    ("OD-003", 1200, 0.05),
    ("OD-005", 2000, 0.03),
    ("OD-007", 1800, 0.06),
    ("OD-008",  900, 0.07),
]
rows = []
for name, qi, di in wells_meta:
    for m in months:
        rows.append({"well": name, "month": int(m), "oil_bopd": float(qi * np.exp(-di * m))})
df = pd.DataFrame(rows)

fig, ax = plt.subplots(figsize=(10, 5))
for well, group in df.groupby("well"):
    ax.plot(group["month"], group["oil_bopd"], linewidth=1.6, label=well)

ax.set_xlabel("Month")
ax.set_ylabel("Oil rate (bopd)")
ax.set_title("Field oil-rate history by well")
ax.legend(title="Well", loc="upper right")
ax.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()

lockCopying code is a Full Access feature.