fitness_center
Exercise 5.8
Field Bubble Map
Level 2
Chapter 5: Data Visualization & PlottingdescriptionProblem
A bubble map is the fastest way to spot spatial patterns across a field: high-water-cut wells clustering on one side, the field's biggest producers concentrated near a structural high, etc.
The starter has 10 wells with lat, lon, oil_bopd, and water_cut.
Build the map:
ax.scatter(lon, lat, ...). Pass two visual encodings:
s = oil_bopd / 5: bubble size proportional to current ratec = water_cut,cmap="RdYlGn_r": colour by water cut
(green = low, red = high; the _r reverses the default).
- Add a colour bar with label
"Water cut"(fig.colorbar(...)). - Annotate each well with its name (
ax.annotate(name, (lon, lat), ...)). - Axis labels (
"Longitude","Latitude"), title, light grid.
lightbulbHints (0/4)
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 pandas as pd
import matplotlib.pyplot as plt
field = pd.DataFrame({
"well": ["OD-001","OD-002","OD-003","OD-004","OD-005",
"OD-006","OD-007","OD-008","OD-009","OD-010"],
"lon": [7.005, 7.012, 7.008, 7.018, 7.001,
7.022, 6.998, 7.015, 7.010, 7.020],
"lat": [4.770, 4.775, 4.768, 4.778, 4.772,
4.780, 4.766, 4.776, 4.770, 4.782],
"oil_bopd": [1842, 320, 1155, 620, 2210, 85, 2950, 410, 1520, 780],
"water_cut": [0.42, 0.88, 0.56, 0.71, 0.22, 0.92, 0.08, 0.65, 0.34, 0.78],
})
fig, ax = plt.subplots(figsize=(8, 6))
sc = ax.scatter(
field["lon"], field["lat"],
s=field["oil_bopd"] / 5,
c=field["water_cut"],
cmap="RdYlGn_r",
alpha=0.8, edgecolors="black", linewidths=0.7,
)
cbar = fig.colorbar(sc, ax=ax)
cbar.set_label("Water cut")
for _, row in field.iterrows():
ax.annotate(row["well"], (row["lon"], row["lat"]),
xytext=(6, 6), textcoords="offset points",
fontsize=8, color="#333")
ax.set_xlabel("Longitude")
ax.set_ylabel("Latitude")
ax.set_title("OML 58 - current oil rate (size) and water cut (color)")
ax.grid(True, alpha=0.25)
plt.tight_layout()
plt.show()
lockCopying code is a Full Access feature.