Fix icon resolution: imshow + interpolation="none" embeds icons unsampled
The OffsetImage path composites at figure dpi, so the icons were going into the PDF as 39x39 bitmaps regardless of source resolution (pdfimages-verified; this is why the SVG switch changed nothing visually). Placing them as AxesImage with interpolation="none" embeds the full 1024 px rasterisation with a scaling transform: 4719 ppi at the placed size, print-crisp. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BkRLcc18rwT2Lysu6PbG7v
This commit is contained in:
parent
c9c4d927ad
commit
438931d67b
3 changed files with 10 additions and 5 deletions
|
|
@ -54,7 +54,7 @@ def _icon(svg_name: str):
|
|||
svg = OUT / "icons" / svg_name
|
||||
with tempfile.NamedTemporaryFile(suffix=".png") as f:
|
||||
try:
|
||||
subprocess.run(["rsvg-convert", "-w", "2048", "-h", "2048", "-o", f.name, str(svg)],
|
||||
subprocess.run(["rsvg-convert", "-w", "1024", "-h", "1024", "-o", f.name, str(svg)],
|
||||
check=True, capture_output=True)
|
||||
except FileNotFoundError as e:
|
||||
raise RuntimeError("rsvg-convert (librsvg) is required to rasterise the icon SVGs "
|
||||
|
|
@ -122,8 +122,6 @@ def fig1a():
|
|||
xs = [x0, x0 + cw + sep, x0 + 2 * cw + sep]
|
||||
row_h, row_top = 0.157, 0.805
|
||||
|
||||
from matplotlib.offsetbox import AnnotationBbox, OffsetImage
|
||||
|
||||
for j2, (name, arch, guarantee, edge, face, headfill, textcol, icon) in enumerate(TIERS):
|
||||
x = xs[j2]
|
||||
xc = x + cw / 2 - 0.02 # text centred left of the icon slot
|
||||
|
|
@ -135,9 +133,16 @@ def fig1a():
|
|||
linespacing=1.3, color=textcol)
|
||||
ax.text(xc, 0.833, guarantee, ha="center", va="bottom", fontsize=6.4,
|
||||
style="italic", color=textcol, alpha=0.85)
|
||||
# Reason: imshow + interpolation="none" embeds the icon unsampled in the PDF (an
|
||||
# OffsetImage is always composited at figure dpi, i.e. ~39 px, whatever the source).
|
||||
img = _icon(icon)
|
||||
ax.add_artist(AnnotationBbox(OffsetImage(img, zoom=28.0 / img.shape[0]),
|
||||
(x + cw - gap - 0.024, 0.902), frameon=False))
|
||||
iw = 28.0 / 1140.0 # 28 display px on an 11.4in/100dpi fig
|
||||
ih = iw * 11.4 / 5.3
|
||||
icx, icy = x + cw - gap - 0.024, 0.902
|
||||
ax.imshow(img, extent=(icx - iw / 2, icx + iw / 2, icy - ih / 2, icy + ih / 2),
|
||||
interpolation="none", aspect="auto", zorder=5)
|
||||
ax.set_xlim(0, 1)
|
||||
ax.set_ylim(0, 1)
|
||||
|
||||
for i2, (label, definition, cells) in enumerate(ROWS):
|
||||
tags = TAGS[i2]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue