Layout Elements =============== Title, scale bar, and source attribution are **chrome** elements set with convenience methods on the map (``m.title`` / ``m.scale_bar`` / ``m.source`` / ``m.north_arrow``). Zoom windows and cartouches remain dict-based methods; the graticule is a :class:`~mappyng.GraticuleLayer`. Title ----- The first argument is the title text; the rest are keyword options. .. code-block:: python m.title( "Population par département", subtitle="Source : INSEE, 2024", loc="left", font_size=14, font_weight="bold", top_gap=10, offset_x=0, offset_y=0, ) .. list-table:: :header-rows: 1 :widths: 22 12 66 * - Key - Default - Description * - ``text`` - required - Title text. Wrapped automatically at ``max_chars``. * - ``subtitle`` - ``None`` - Subtitle rendered below the title. * - ``loc`` - ``"left"`` - Horizontal alignment: ``"left"``, ``"center"``, or ``"right"``. * - ``max_chars`` - 60 - Maximum characters per line before wrapping. * - ``font_size`` - from style - Title font size (scaled by ``font_scale``). * - ``fill`` - from style - Title color. * - ``font_weight`` - from style - Font weight (e.g. ``"bold"``). * - ``font_family`` - from style - Font family. * - ``subtitle_font_size`` - auto - Subtitle font size (defaults to ``font_size × 0.75``). * - ``subtitle_color`` - from style - Subtitle color. * - ``subtitle_font_weight`` - ``"normal"`` - Subtitle font weight. * - ``top_gap`` - 8 - Gap between title baseline and map top edge (SVG px). Positive = title moves up. * - ``offset_x`` - 0.0 - Additional horizontal shift (SVG px). * - ``offset_y`` - 0.0 - Additional vertical shift (SVG px). Scale bar --------- .. code-block:: python m.scale_bar() # fully automatic m.scale_bar(length=200_000, label="200 km") m.scale_bar(location="lower left", color="#444444", bar_height=4, opacity=0.8) .. list-table:: :header-rows: 1 :widths: 22 15 63 * - Key - Default - Description * - ``length`` - auto - Bar length in map CRS units. Auto: ~20 % of map width. * - ``label`` - auto - Label text. Auto-generated from ``length / unit_factor``. Pass ``""`` to suppress. * - ``unit`` - ``"km"`` - Unit string appended to auto-label. * - ``unit_factor`` - 1000 - Divisor for CRS-units to display-units (default: metres to km). * - ``location`` - ``"lower right"`` - Preset position: ``"lower right"``, ``"lower left"``, ``"upper right"``, ``"upper left"``. * - ``position`` - ``None`` - Manual position ``{"x": frac, "y": frac}`` (overrides ``location``). * - ``color`` - from style - Unified color for bar, ticks, and label. * - ``bar_color`` - from ``color`` - Bar line color override. * - ``tick_color`` - from ``color`` - Tick color override. * - ``label_color`` - from ``color`` - Label color override. * - ``font_size`` - 8 - Label font size. * - ``font_weight`` - ``"normal"`` - Label font weight. * - ``font_family`` - from style - Label font family. * - ``bar_height`` - 3 - Bar line thickness (SVG px). * - ``tick_height`` - ``bar_height + 3`` - Tick mark height (SVG px). * - ``tick_width`` - 1 - Tick stroke width (SVG px). * - ``margin`` - 15 - Distance from the content edge to the bar (SVG px). * - ``alpha`` - 1.0 - Overall opacity 0-1. Source attribution ------------------ .. code-block:: python m.source("Source : INSEE") m.source("Source : INSEE\\nTraitement : auteur", layout="horizontal") m.source("Source : IGN", position={"x": 0.5, "y": 1.05}) .. list-table:: :header-rows: 1 :widths: 22 15 63 * - Key - Default - Description * - ``text`` - required - Attribution text. Use ``"\\n"`` for line breaks in horizontal mode. * - ``layout`` - ``"vertical"`` - ``"vertical"``, rotated 90° at the right edge, reading bottom-to-top. ``"horizontal"``, normal text at the bottom-right. * - ``position`` - ``None`` - Manual position ``{"x": frac, "y": frac}`` (overrides ``layout``). * - ``rotation`` - 90 / 0 - Explicit rotation in degrees (default depends on layout). * - ``font_size`` - from style - Font size. * - ``color`` - from style - Text color. * - ``alpha`` - from style - Text opacity. * - ``font_style`` - ``"italic"`` - CSS font-style. * - ``font_weight`` - ``"normal"`` - CSS font-weight. * - ``font_family`` - from style - Font family. * - ``text_anchor`` - auto - SVG text-anchor: ``"start"``, ``"middle"``, or ``"end"``. Zoom window (``add_zoom``) -------------------------- .. code-block:: python m.add_zoom({ "bbox": [586377, 6780533, 739396, 6904563], "border_radius": 8, "box_shadow": True, "glow": False, }) .. list-table:: :header-rows: 1 :widths: 22 15 63 * - Key - Default - Description * - ``bbox`` - required - Geographic bounding box ``[minx, miny, maxx, maxy]``. * - ``x`` / ``y`` - auto - SVG pixel position of the zoom window top-left corner. * - ``width`` / ``height`` - auto - Zoom window size in SVG px. * - ``border_color`` - from style - Border stroke color. * - ``border_width`` - 1 - Border stroke width (SVG px). * - ``border_radius`` - 4 - Corner radius (SVG px, 0 = sharp). * - ``box_shadow`` - ``None`` - Drop shadow: ``True`` (defaults), ``False``, or dict (keys: ``dx``, ``dy``, ``blur``, ``color``, ``opacity``). * - ``glow`` - ``None`` - Outer glow: same format as ``box_shadow``. Graticule (:class:`~mappyng.GraticuleLayer`) -------------------------------------------- .. code-block:: python from mappyng import GraticuleLayer m.add(GraticuleLayer(step=5.0, stroke="#888888", opacity=0.4, stroke_width=0.5, dash="4 2")) .. list-table:: :header-rows: 1 :widths: 22 12 66 * - Key - Default - Description * - ``step`` - 10.0 - Graticule spacing in degrees. * - ``color`` - ``"#aaaaaa"`` - Line color. * - ``opacity`` - 0.5 - Line opacity. * - ``stroke_width`` - 0.5 - Line width (SVG px). * - ``dash`` - ``"4 2"`` - SVG ``stroke-dasharray``.