Skip to content

Commit 886e84a

Browse files
fix(matplotlib): address review feedback for column-stratigraphic
Attempt 1/3 - fixes based on AI review
1 parent 9fe2e38 commit 886e84a

1 file changed

Lines changed: 109 additions & 30 deletions

File tree

plots/column-stratigraphic/implementations/matplotlib.py

Lines changed: 109 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
""" pyplots.ai
1+
"""pyplots.ai
22
column-stratigraphic: Stratigraphic Column with Lithology Patterns
33
Library: matplotlib 3.10.8 | Python 3.14.3
44
Quality: 87/100 | Created: 2026-03-15
55
"""
66

77
import matplotlib.patches as mpatches
88
import matplotlib.pyplot as plt
9+
import numpy as np
910

1011

1112
# Data - synthetic sedimentary borehole section (depth increasing downward, younger at top)
@@ -31,13 +32,46 @@
3132
"conglomerate": {"color": "#DEB887", "hatch": "ooo", "edgecolor": "#8B6914"},
3233
}
3334

35+
# Age group background colors for subtle shading
36+
age_colors = {
37+
"Miocene": "#FFF8E7",
38+
"Oligocene": "#F5F0E0",
39+
"Eocene": "#EDE8D8",
40+
"Cretaceous": "#E8EEF5",
41+
"Jurassic": "#F0E8E0",
42+
}
43+
3444
# Plot
35-
fig, ax = plt.subplots(figsize=(10, 16))
45+
fig, ax = plt.subplots(figsize=(12, 16))
3646

37-
column_left = 0.0
38-
column_width = 3.0
47+
column_left = 1.5
48+
column_width = 5.0
3949
max_depth = 200
4050

51+
# Compute age spans
52+
age_spans = {}
53+
for layer in layers:
54+
age = layer["age"]
55+
if age not in age_spans:
56+
age_spans[age] = {"top": layer["top"], "bottom": layer["bottom"]}
57+
else:
58+
age_spans[age]["top"] = min(age_spans[age]["top"], layer["top"])
59+
age_spans[age]["bottom"] = max(age_spans[age]["bottom"], layer["bottom"])
60+
61+
# Draw subtle age-group background shading
62+
for age, span in age_spans.items():
63+
bg_rect = mpatches.FancyBboxPatch(
64+
(column_left - 0.1, span["top"]),
65+
column_width + 0.2,
66+
span["bottom"] - span["top"],
67+
boxstyle="square,pad=0",
68+
facecolor=age_colors[age],
69+
edgecolor="none",
70+
zorder=0,
71+
)
72+
ax.add_patch(bg_rect)
73+
74+
# Draw lithology layers
4175
for layer in layers:
4276
top = layer["top"]
4377
bottom = layer["bottom"]
@@ -53,36 +87,76 @@
5387
edgecolor=style["edgecolor"],
5488
linewidth=1.5,
5589
hatch=style["hatch"],
90+
zorder=1,
5691
)
5792
ax.add_patch(rect)
5893

5994
mid_depth = (top + bottom) / 2
6095
ax.text(
61-
column_left + column_width + 0.3,
96+
column_left + column_width + 0.4,
6297
mid_depth,
6398
layer["formation"],
64-
fontsize=14,
99+
fontsize=16,
65100
va="center",
66101
ha="left",
67-
fontweight="medium",
102+
fontweight="semibold",
103+
color="#2C2C2C",
68104
)
69105

70-
# Age labels on the left with bracket lines
71-
age_spans = {}
72-
for layer in layers:
73-
age = layer["age"]
74-
if age not in age_spans:
75-
age_spans[age] = {"top": layer["top"], "bottom": layer["bottom"]}
76-
else:
77-
age_spans[age]["top"] = min(age_spans[age]["top"], layer["top"])
78-
age_spans[age]["bottom"] = max(age_spans[age]["bottom"], layer["bottom"])
106+
# Unconformity between Eocene (Chadron Fm, bottom=72) and Cretaceous (Niobrara Fm, top=72)
107+
unconformity_depth = 72
108+
x_wave = np.linspace(column_left, column_left + column_width, 80)
109+
y_wave = unconformity_depth + 0.8 * np.sin(x_wave * 4)
110+
ax.plot(x_wave, y_wave, color="#B22222", linewidth=2.5, zorder=3)
111+
ax.text(
112+
column_left + column_width + 0.4,
113+
unconformity_depth,
114+
"unconformity",
115+
fontsize=14,
116+
va="center",
117+
ha="left",
118+
fontstyle="italic",
119+
color="#B22222",
120+
fontweight="medium",
121+
)
79122

123+
# Age labels on the left with bracket lines
124+
bracket_x = column_left - 1.2
80125
for age, span in age_spans.items():
81126
mid = (span["top"] + span["bottom"]) / 2
82-
ax.annotate(age, xy=(-0.3, mid), fontsize=13, va="center", ha="right", fontstyle="italic", color="#333333")
83-
ax.plot([-0.15, -0.05], [span["top"], span["top"]], color="#333333", linewidth=1.0, clip_on=False)
84-
ax.plot([-0.15, -0.05], [span["bottom"], span["bottom"]], color="#333333", linewidth=1.0, clip_on=False)
85-
ax.plot([-0.1, -0.1], [span["top"], span["bottom"]], color="#333333", linewidth=1.0, clip_on=False)
127+
ax.text(
128+
column_left - 1.8,
129+
mid,
130+
age,
131+
fontsize=16,
132+
va="center",
133+
ha="center",
134+
fontstyle="italic",
135+
color="#333333",
136+
fontweight="medium",
137+
clip_on=False,
138+
)
139+
ax.plot(
140+
[bracket_x, bracket_x + 0.4],
141+
[span["top"] + 0.5, span["top"] + 0.5],
142+
color="#555555",
143+
linewidth=1.2,
144+
clip_on=False,
145+
)
146+
ax.plot(
147+
[bracket_x, bracket_x + 0.4],
148+
[span["bottom"] - 0.5, span["bottom"] - 0.5],
149+
color="#555555",
150+
linewidth=1.2,
151+
clip_on=False,
152+
)
153+
ax.plot(
154+
[bracket_x + 0.2, bracket_x + 0.2],
155+
[span["top"] + 0.5, span["bottom"] - 0.5],
156+
color="#555555",
157+
linewidth=1.2,
158+
clip_on=False,
159+
)
86160

87161
# Legend
88162
legend_handles = []
@@ -98,25 +172,30 @@
98172

99173
ax.legend(
100174
handles=legend_handles,
101-
loc="lower right",
102-
fontsize=13,
103-
framealpha=0.9,
104-
edgecolor="#cccccc",
175+
loc="upper center",
176+
bbox_to_anchor=(0.55, -0.03),
177+
fontsize=16,
178+
framealpha=0.95,
179+
edgecolor="#bbbbbb",
180+
fancybox=True,
181+
shadow=True,
105182
title="Lithology",
106-
title_fontsize=14,
183+
title_fontsize=17,
184+
borderpad=1.0,
185+
ncol=5,
107186
)
108187

109188
# Style
110-
ax.set_xlim(-2.5, column_left + column_width + 4.5)
189+
ax.set_xlim(column_left - 2.8, column_left + column_width + 4.5)
111190
ax.set_ylim(max_depth, 0)
112-
ax.set_ylabel("Depth (m)", fontsize=20)
113-
ax.set_title("column-stratigraphic · matplotlib · pyplots.ai", fontsize=24, fontweight="medium", pad=20)
114-
ax.tick_params(axis="y", labelsize=16)
191+
ax.set_ylabel("Depth (m)", fontsize=20, labelpad=10)
192+
ax.set_title("column-stratigraphic · matplotlib · pyplots.ai", fontsize=24, fontweight="medium", pad=25)
193+
ax.tick_params(axis="y", labelsize=16, length=6)
115194
ax.set_xticks([])
116195
ax.spines["top"].set_visible(False)
117196
ax.spines["right"].set_visible(False)
118197
ax.spines["bottom"].set_visible(False)
119-
ax.yaxis.grid(True, alpha=0.15, linewidth=0.8)
198+
ax.yaxis.grid(True, alpha=0.12, linewidth=0.8, linestyle="--")
120199

121200
plt.tight_layout()
122201
plt.savefig("plot.png", dpi=300, bbox_inches="tight")

0 commit comments

Comments
 (0)