Skip to content

Commit d52015e

Browse files
fix(bokeh): address review feedback for column-stratigraphic
Attempt 2/3 - fixes based on AI review
1 parent c6bd926 commit d52015e

1 file changed

Lines changed: 80 additions & 30 deletions

File tree

  • plots/column-stratigraphic/implementations

plots/column-stratigraphic/implementations/bokeh.py

Lines changed: 80 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
""" pyplots.ai
1+
"""pyplots.ai
22
column-stratigraphic: Stratigraphic Column with Lithology Patterns
33
Library: bokeh 3.9.0 | Python 3.14.3
44
Quality: 85/100 | Created: 2026-03-15
@@ -23,30 +23,31 @@
2323
{"top": 180, "bottom": 200, "lithology": "Siltstone", "formation": "Uinta Fm", "age": "Eocene"},
2424
]
2525

26-
# Lithology style mapping: color, hatch_pattern (improved color differentiation)
26+
# Lithology style mapping: improved colorblind-safe palette
27+
# Sandstone: warm yellow, Siltstone: olive green (high contrast vs sandstone)
2728
lithology_styles = {
2829
"Sandstone": {"color": "#F5DEB3", "hatch_pattern": ".", "hatch_color": "#8B7355"},
2930
"Shale": {"color": "#A9A9A9", "hatch_pattern": "-", "hatch_color": "#4A4A4A"},
3031
"Limestone": {"color": "#87CEEB", "hatch_pattern": "+", "hatch_color": "#2E5A88"},
31-
"Siltstone": {"color": "#8B6F5E", "hatch_pattern": "/", "hatch_color": "#3E2F23"},
32+
"Siltstone": {"color": "#7B9971", "hatch_pattern": "/", "hatch_color": "#3B5335"},
3233
"Conglomerate": {"color": "#E8923F", "hatch_pattern": "o", "hatch_color": "#6B3A00"},
3334
}
3435

35-
# K-Pg boundary depth (between Fox Hills Fm / Late Cretaceous and Dawson Fm / Paleocene)
36+
# K-Pg boundary depth
3637
KPG_DEPTH = 88
3738

38-
# Column x-position and width (wider column for better canvas use)
39-
col_center = 0.5
40-
col_width = 1.0
39+
# Column geometry — wider for better canvas fill
40+
col_center = 0.55
41+
col_width = 1.1
4142

42-
# Plot (tighter x_range for better horizontal utilization)
43+
# Plot tighter x_range for better horizontal utilization
4344
p = figure(
4445
width=4800,
4546
height=2700,
4647
title="column-stratigraphic · bokeh · pyplots.ai",
4748
y_axis_label="Depth (m)",
4849
toolbar_location=None,
49-
x_range=Range1d(-0.7, 2.0),
50+
x_range=Range1d(-0.55, 1.85),
5051
y_range=Range1d(210, -10),
5152
)
5253

@@ -102,31 +103,51 @@
102103
)
103104
p.add_tools(hover)
104105

105-
# K-Pg boundary emphasis — bold red dashed line with annotation
106-
kpg_span = Span(location=KPG_DEPTH, dimension="width", line_color="#CC0000", line_width=4, line_dash="dashed")
106+
# Depth tick marks at each layer boundary for polished geological appearance
107+
boundary_depths = sorted({layer["top"] for layer in layers} | {layer["bottom"] for layer in layers})
108+
for depth in boundary_depths:
109+
x_left = col_center - col_width / 2
110+
p.line(x=[x_left - 0.04, x_left], y=[depth, depth], line_color="#555555", line_width=1.5, line_alpha=0.6)
111+
# Small depth label at boundary
112+
label = Label(
113+
x=x_left - 0.06,
114+
y=depth,
115+
text=f"{depth:.0f}",
116+
text_font_size="13pt",
117+
text_align="right",
118+
text_baseline="middle",
119+
text_color="#777777",
120+
)
121+
p.add_layout(label)
122+
123+
# K-Pg boundary emphasis — bold red dashed line with prominent annotation
124+
kpg_span = Span(location=KPG_DEPTH, dimension="width", line_color="#CC0000", line_width=5, line_dash="dashed")
107125
p.add_layout(kpg_span)
108126

109127
kpg_label = Label(
110128
x=col_center,
111129
y=KPG_DEPTH,
112130
text="K-Pg Boundary (~66 Ma)",
113-
text_font_size="16pt",
131+
text_font_size="20pt",
114132
text_font_style="bold",
115133
text_color="#CC0000",
116134
text_align="center",
117135
text_baseline="bottom",
118-
y_offset=8,
136+
y_offset=10,
137+
background_fill_color="white",
138+
background_fill_alpha=0.8,
119139
)
120140
p.add_layout(kpg_label)
121141

122-
# Formation labels on the right side
142+
# Formation labels on the right side — closer to column
123143
for layer in layers:
124144
mid_y = (layer["top"] + layer["bottom"]) / 2
125145
label = Label(
126-
x=1.08,
146+
x=col_center + col_width / 2 + 0.04,
127147
y=mid_y,
128148
text=layer["formation"],
129-
text_font_size="18pt",
149+
text_font_size="19pt",
150+
text_font_style="bold",
130151
text_align="left",
131152
text_baseline="middle",
132153
text_color="#2C2C2C",
@@ -143,54 +164,83 @@
143164
age_groups[age]["bottom"] = max(age_groups[age]["bottom"], layer["bottom"])
144165
age_groups[age]["top"] = min(age_groups[age]["top"], layer["top"])
145166

167+
bracket_x = -0.12
146168
for age, bounds in age_groups.items():
147169
mid_y = (bounds["top"] + bounds["bottom"]) / 2
148170
label = Label(
149-
x=-0.08,
171+
x=bracket_x - 0.04,
150172
y=mid_y,
151173
text=age,
152-
text_font_size="18pt",
174+
text_font_size="19pt",
153175
text_align="right",
154176
text_baseline="middle",
155177
text_color="#2C2C2C",
156178
text_font_style="italic",
157179
)
158180
p.add_layout(label)
159181

160-
p.line(x=[-0.05, -0.05], y=[bounds["top"], bounds["bottom"]], line_color="#2C2C2C", line_width=2)
161-
p.line(x=[-0.07, -0.05], y=[bounds["top"], bounds["top"]], line_color="#2C2C2C", line_width=2)
162-
p.line(x=[-0.07, -0.05], y=[bounds["bottom"], bounds["bottom"]], line_color="#2C2C2C", line_width=2)
182+
# Bracket lines
183+
p.line(x=[bracket_x, bracket_x], y=[bounds["top"] + 1, bounds["bottom"] - 1], line_color="#2C2C2C", line_width=2.5)
184+
p.line(
185+
x=[bracket_x - 0.025, bracket_x], y=[bounds["top"] + 1, bounds["top"] + 1], line_color="#2C2C2C", line_width=2.5
186+
)
187+
p.line(
188+
x=[bracket_x - 0.025, bracket_x],
189+
y=[bounds["bottom"] - 1, bounds["bottom"] - 1],
190+
line_color="#2C2C2C",
191+
line_width=2.5,
192+
)
163193

164-
# Legend — positioned adjacent to column, not in far corner
194+
# Legend — positioned adjacent to column on right side
165195
legend_items = [LegendItem(label=lith, renderers=[rend]) for lith, rend in legend_items_dict.items()]
166196
legend = Legend(
167197
items=legend_items,
168198
location="top_right",
169199
label_text_font_size="20pt",
170-
spacing=12,
200+
spacing=14,
171201
padding=20,
172-
background_fill_alpha=0.85,
173-
glyph_height=30,
174-
glyph_width=30,
202+
margin=10,
203+
background_fill_color="#F5F5F0",
204+
background_fill_alpha=0.9,
205+
border_line_color="#CCCCCC",
206+
border_line_width=1,
207+
glyph_height=32,
208+
glyph_width=32,
175209
title="Lithology",
176210
title_text_font_size="22pt",
177211
title_text_font_style="bold",
178212
)
179213
p.add_layout(legend, "right")
180214

181-
# Style
215+
# Typography hierarchy
182216
p.title.text_font_size = "36pt"
217+
p.title.text_color = "#1A1A1A"
218+
p.title.offset = 10
183219
p.yaxis.axis_label_text_font_size = "28pt"
220+
p.yaxis.axis_label_text_font_style = "bold"
221+
p.yaxis.axis_label_text_color = "#333333"
184222
p.yaxis.major_label_text_font_size = "22pt"
223+
p.yaxis.major_label_text_color = "#444444"
185224

225+
# Visual refinement
186226
p.xaxis.visible = False
187227
p.xgrid.grid_line_color = None
188-
p.ygrid.grid_line_alpha = 0.15
189-
p.ygrid.grid_line_dash = "dashed"
228+
p.ygrid.grid_line_alpha = 0.12
229+
p.ygrid.grid_line_dash = [4, 4]
230+
p.ygrid.grid_line_color = "#999999"
190231

191232
p.yaxis.minor_tick_line_color = None
233+
p.yaxis.major_tick_line_color = "#AAAAAA"
234+
p.yaxis.axis_line_color = "#888888"
192235
p.outline_line_color = None
193-
p.background_fill_color = "#FAFAFA"
236+
p.background_fill_color = "#FAFAF6"
237+
p.border_fill_color = "#FFFFFF"
238+
239+
# Padding
240+
p.min_border_left = 100
241+
p.min_border_right = 40
242+
p.min_border_top = 60
243+
p.min_border_bottom = 60
194244

195245
# Save
196246
export_png(p, filename="plot.png")

0 commit comments

Comments
 (0)