Exerciseschevron_rightChapter 5chevron_right5.9
fitness_center

Exercise 5.9

Cumulative Production with Milestones

Level 2
Chapter 5: Data Visualization & Plotting
descriptionProblem

A cumulative production curve is more readable when annotated with the milestones it crossed. Build one for a single well over 36 months, then mark when the well first crossed 100,000 STB and 250,000 STB cumulative production.

The starter generates a daily oil-rate series sampled monthly.

Required:

  1. Compute cum_stb = np.cumsum(rate * 30) (approx. days/month).
  2. Plot cum_stb / 1000 (in kSTB) against month on the main axis.
  3. Find month_100k, the first month at which `cum_stb >=

100_000`.

  1. Find month_250k, the first month at which `cum_stb >=

250_000`.

  1. Add a vertical reference line (ax.axvline) at each of those

months, with a text label naming the milestone.

  1. Axis labels, title, light grid.
lightbulbHints (0/3)

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 matplotlib.pyplot as plt

months = np.arange(0, 36)
rate = 1500 * np.exp(-0.04 * months)

cum_stb = np.cumsum(rate * 30)
month_100k = int(np.argmax(cum_stb >= 100_000))
month_250k = int(np.argmax(cum_stb >= 250_000))

fig, ax = plt.subplots(figsize=(10, 5))
ax.plot(months, cum_stb / 1000, color="#2E8B57", linewidth=2, label="Cumulative oil")
ax.fill_between(months, 0, cum_stb / 1000, alpha=0.1, color="#2E8B57")

for milestone, month in [("100 kSTB", month_100k), ("250 kSTB", month_250k)]:
    ax.axvline(month, color="#888", linestyle="--", linewidth=1)
    ax.text(month + 0.3, ax.get_ylim()[1] * 0.05, milestone,
            rotation=90, fontsize=9, color="#666")

ax.set_xlabel("Month")
ax.set_ylabel("Cumulative oil (kSTB)")
ax.set_title("Cumulative production with milestones")
ax.grid(True, alpha=0.3)
ax.legend()
plt.tight_layout()
plt.show()

lockCopying code is a Full Access feature.