Source code for figrecipe._qr

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""QR-code overlay for figure-level metadata visualization.

Adds a minimal QR code to a matplotlib figure encoding arbitrary
metadata (typically a URL + provenance dict). Used for embedding
reproducibility / source links directly on a publication-ready figure.

Migrated from ``scitex.io._qr_utils`` (2026-05-29) per SoC: QR
annotation is figure-domain, not I/O-domain.
"""

from __future__ import annotations

import json
import logging

logger = logging.getLogger(__name__)


[docs] def add_qr_to_figure(fig, metadata, position="bottom-right", size=0.08): """Add a minimal QR code to a matplotlib figure. Parameters ---------- fig : matplotlib.figure.Figure Target figure to overlay onto. metadata : dict Payload to encode. If ``"url"`` is absent, ``"https://scitex.ai"`` is added so the QR resolves to something even when consumers don't provide one. position : str One of ``"bottom-right"``, ``"bottom-left"``, ``"top-right"``, ``"top-left"``. Unknown values fall back to ``"bottom-right"``. size : float Relative size of the QR overlay (fraction of figure width). Returns ------- matplotlib.figure.Figure The same figure, with a QR overlay axes added. If the optional ``qrcode`` / ``Pillow`` dependencies are not installed, the figure is returned unmodified and a warning is logged. """ try: import qrcode except ImportError: logger.warning( "qrcode library not available. Install with: pip install qrcode[pil]" ) return fig if "url" not in metadata: metadata = dict(metadata) metadata["url"] = "https://scitex.ai" metadata_json = json.dumps(metadata, ensure_ascii=False) qr = qrcode.QRCode( version=1, error_correction=qrcode.constants.ERROR_CORRECT_L, box_size=2, border=1, ) qr.add_data(metadata_json) qr.make(fit=True) qr_img = qr.make_image(fill_color="black", back_color="white") positions = { "bottom-right": (0.92, 0.02), "bottom-left": (0.02, 0.02), "top-right": (0.92, 0.88), "top-left": (0.02, 0.88), } if position not in positions: position = "bottom-right" x, y = positions[position] ax_qr = fig.add_axes( [x, y, size, size * (fig.get_figheight() / fig.get_figwidth())] ) ax_qr.imshow(qr_img, cmap="gray") ax_qr.axis("off") return fig
__all__ = ["add_qr_to_figure"]