value maps: edge-inset labels + roomier margin so pole/edge labels don't clip the frame

allocate_labels now keeps a few px inside the axes (edge_pad), so a label pushed toward
the frame (e.g. Serbia against the Adaptive pole) can't render flush-clipped; and the
value-map margin goes 0.13 -> 0.17 so the pole signposts sit in a real inner margin.

Co-Authored-By: Claudypoo <288921227+claudypoo@users.noreply.github.com>
This commit is contained in:
wassname
2026-07-05 17:15:45 +08:00
co-authored by Claudypoo
parent 9f16db0bfb
commit a7c1bab7e6
2 changed files with 6 additions and 5 deletions
+4 -3
View File
@@ -87,7 +87,7 @@ def allocate_labels(ax, anchor_sets: list[np.ndarray], texts: list[str], colors:
region: list[bool] | None = None, fontsize: float = 9.0,
fontsizes: list[float] | None = None, styles: list[str] | None = None,
anchor_pad: list[float] | None = None, gap_frac: float = 0.28,
spacing_x: float = 0.4, spacing_y: float = 0.3,
spacing_x: float = 0.4, spacing_y: float = 0.3, edge_pad: float = 4.0,
stroke: float = 2.0, linecolor: str = "#9a958a", linewidth: float = 0.6):
"""Place N labels. See the module docstring for the model. Draws directly onto `ax`.
@@ -142,8 +142,9 @@ def allocate_labels(ax, anchor_sets: list[np.ndarray], texts: list[str], colors:
cx, cy = ax0 + ux * (rx + w_i / 2), ay0 + uy * (ry + h_i / 2)
box = (cx - w_i / 2 - gap, cy - h_i / 2 - gap, cx + w_i / 2 + gap, cy + h_i / 2 + gap)
pen = 0.0
if box[0] < abox.x0 or box[2] > abox.x1 or box[1] < abox.y0 or box[3] > abox.y1:
pen += 1000.0 # off-canvas: last resort
if (box[0] < abox.x0 + edge_pad or box[2] > abox.x1 - edge_pad or
box[1] < abox.y0 + edge_pad or box[3] > abox.y1 - edge_pad):
pen += 1000.0 # off-canvas / flush-to-frame: last resort
inside, clear = _box_metrics(box, obstacles)
pen += 50.0 * inside
for pb in placed: # overlap area with settled labels
+2 -2
View File
@@ -329,8 +329,8 @@ def plot_value_map(display: str, countries: list[str], P: np.ndarray,
lab_specs.append((bx, by, blab, C_BASE, "bold", 8.0))
obs_x.append(bx); obs_y.append(by)
ax.margins(0.13)
if invert_x: # e.g. Self-expression on the LEFT. Flip BEFORE
ax.margins(0.17) # roomy edges: the pole signposts sit in the inner
if invert_x: # margin and edge labels (Serbia, Adaptive) need to fit; e.g. Self-expression on the LEFT. Flip BEFORE
ax.invert_xaxis() # placement so the pixel-space allocator sees the
ax.autoscale(False) # final orientation (else every label mirrors left).
# ONE placement pass for everything (see labelplace.allocate_labels). Each zone name is a REGION