From e9ef6e440084dcac6dbec2e5026c17063b7e780f Mon Sep 17 00:00:00 2001 From: Alessandro Santini Date: Tue, 4 Aug 2026 16:32:15 +0200 Subject: [PATCH 1/6] Added the palette in utils/colors.py --- qoolqit/__init__.py | 1 + qoolqit/utils/__init__.py | 4 ++ qoolqit/utils/colors.py | 104 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 109 insertions(+) create mode 100644 qoolqit/utils/__init__.py create mode 100644 qoolqit/utils/colors.py diff --git a/qoolqit/__init__.py b/qoolqit/__init__.py index cd11c0386..270c948ce 100644 --- a/qoolqit/__init__.py +++ b/qoolqit/__init__.py @@ -18,6 +18,7 @@ from qoolqit.execution.sequence_compiler import SequenceCompiler from qoolqit.program import QuantumProgram from qoolqit.register import Register +from qoolqit.utils import colors from qoolqit.waveforms import ( BlackmanWaveform, ConstantWaveform, diff --git a/qoolqit/utils/__init__.py b/qoolqit/utils/__init__.py new file mode 100644 index 000000000..c34a5b759 --- /dev/null +++ b/qoolqit/utils/__init__.py @@ -0,0 +1,4 @@ +from .colors import COLORMAPS, DIVERGING, PALETTE, SEQUENTIAL + +__all__ = ["PALETTE", "DIVERGING", "SEQUENTIAL", "COLORMAPS"] + diff --git a/qoolqit/utils/colors.py b/qoolqit/utils/colors.py new file mode 100644 index 000000000..6dbde3613 --- /dev/null +++ b/qoolqit/utils/colors.py @@ -0,0 +1,104 @@ +"""PASQAL/QoolQit brand colors and colormaps for Matplotlib. + +Importing this module registers extra names with Matplotlib. +Every palette key uses the uniform ``_`` form. +Colors are registered both bare (``"mint_green"``) +and namespaced (``"pasqal:mint_green"``). Colormaps are +``qq__`` for diverging maps and ``qq_`` for sequential ones, +each also available reversed with the usual ``_r`` suffix. + +Examples: + >>> import matplotlib.pyplot as plt + >>> from qoolqit.utils import colors + >>> plt.plot(x, y, color="mint_green") # bare name + >>> plt.plot(x, y, color="pasqal:mint_green") # namespaced (same color) + >>> plt.imshow(data, cmap="qq_purple_mint") +""" + +from __future__ import annotations + +from collections.abc import Mapping, Sequence + +import matplotlib as mpl +import matplotlib.pyplot as plt +from matplotlib.colors import LinearSegmentedColormap + +__all__ = ["PALETTE", "DIVERGING", "SEQUENTIAL", "COLORMAPS", "NAMESPACE", "register"] + +NAMESPACE = "pasqal" + +# Brand palette. Keys use the uniform _ form (see module docstring). +PALETTE: Mapping[str, str] = { + "metal_blue": "#397378", + "neon_purple": "#867BFA", + "mint_green": "#00C887", + "soft_orange": "#FF986E", + "dark_green": "#0F1E23", + "neon_blue": "#92C8E5", + "soft_green": "#173035", + "bright_green": "#E1F6E9", + "neutral_gray": "#506166", +} + +# Colormaps map to palette keys, interpolated in order. Diverging maps go +# ->
-> ; the plain name uses the near-white center, the +# _dark variant the near-black one. +DIVERGING: Mapping[str, Sequence[str]] = { + "qq_purple_mint": ("neon_purple", "bright_green", "mint_green"), + "qq_purple_mint_dark": ("neon_purple", "dark_green", "mint_green"), + "qq_orange_mint": ("soft_orange", "bright_green", "mint_green"), + "qq_orange_mint_dark": ("soft_orange", "dark_green", "mint_green"), + "qq_purple_orange": ("neon_purple", "bright_green", "soft_orange"), + "qq_purple_orange_dark": ("neon_purple", "dark_green", "soft_orange"), + "qq_blue_mint": ("neon_blue", "bright_green", "mint_green"), + "qq_blue_mint_dark": ("neon_blue", "dark_green", "mint_green"), +} + +SEQUENTIAL: Mapping[str, Sequence[str]] = { + "qq_mint": ("bright_green", "mint_green"), + "qq_purple": ("bright_green", "neon_purple"), + "qq_orange": ("bright_green", "soft_orange"), + "qq_deep": ("bright_green", "mint_green", "metal_blue", "dark_green"), + "qq_night": ("dark_green", "metal_blue", "mint_green"), +} + + +def _build_colormaps() -> dict[str, LinearSegmentedColormap]: + """Build every brand colormap plus its reversed ``_r`` variant.""" + cmaps: dict[str, LinearSegmentedColormap] = {} + for name, keys in {**DIVERGING, **SEQUENTIAL}.items(): + cmaps[name] = LinearSegmentedColormap.from_list(name, [PALETTE[key] for key in keys]) + for name in list(cmaps): + cmaps[f"{name}_r"] = cmaps[name].reversed(name=f"{name}_r") + return cmaps + + +COLORMAPS: Mapping[str, LinearSegmentedColormap] = _build_colormaps() + + +def register(bare: bool = True) -> None: + """Register the brand colors and colormaps with Matplotlib. + + Called automatically on import. + + Args: + bare: Also register the palette under its plain keys (``"mint_green"``) + in addition to the namespaced ones (``"pasqal:mint_green"``). Safe + because underscore names cannot collide with Matplotlib built-ins. + """ + names = {f"{NAMESPACE}:{key}": value for key, value in PALETTE.items()} + if bare: + names.update(PALETTE) + mpl.colors.get_named_colors_mapping().update(names) + + for name, cmap in COLORMAPS.items(): + try: # Matplotlib >= 3.6 + if name not in mpl.colormaps: + mpl.colormaps.register(cmap, name=name) + except AttributeError: # older Matplotlib + try: + plt.register_cmap(name=name, cmap=cmap) + except ValueError: # already registered + pass + +register() From cdaa5e7a12e5a216f77e26c03e7ad39adcd32a66 Mon Sep 17 00:00:00 2001 From: Alessandro Santini Date: Tue, 4 Aug 2026 16:38:40 +0200 Subject: [PATCH 2/6] precommit --- qoolqit/utils/__init__.py | 3 ++- qoolqit/utils/colors.py | 30 ++++++++++++++++-------------- 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/qoolqit/utils/__init__.py b/qoolqit/utils/__init__.py index c34a5b759..a10309373 100644 --- a/qoolqit/utils/__init__.py +++ b/qoolqit/utils/__init__.py @@ -1,4 +1,5 @@ +from __future__ import annotations + from .colors import COLORMAPS, DIVERGING, PALETTE, SEQUENTIAL __all__ = ["PALETTE", "DIVERGING", "SEQUENTIAL", "COLORMAPS"] - diff --git a/qoolqit/utils/colors.py b/qoolqit/utils/colors.py index 6dbde3613..290ceb792 100644 --- a/qoolqit/utils/colors.py +++ b/qoolqit/utils/colors.py @@ -1,11 +1,10 @@ """PASQAL/QoolQit brand colors and colormaps for Matplotlib. -Importing this module registers extra names with Matplotlib. -Every palette key uses the uniform ``_`` form. -Colors are registered both bare (``"mint_green"``) -and namespaced (``"pasqal:mint_green"``). Colormaps are -``qq__`` for diverging maps and ``qq_`` for sequential ones, -each also available reversed with the usual ``_r`` suffix. +Importing this module registers extra names with Matplotlib; it never touches +``rcParams``, so existing plots are unaffected. Colors are registered both bare +(``"mint_green"``) and namespaced (``"pasqal:mint_green"``). Colormaps follow +``qq__`` (diverging) and ``qq_`` (sequential), each also +available reversed with the usual ``_r`` suffix. Examples: >>> import matplotlib.pyplot as plt @@ -23,11 +22,12 @@ import matplotlib.pyplot as plt from matplotlib.colors import LinearSegmentedColormap -__all__ = ["PALETTE", "DIVERGING", "SEQUENTIAL", "COLORMAPS", "NAMESPACE", "register"] +__all__ = ["PALETTE", "DIVERGING", "SEQUENTIAL", "COLORMAPS"] NAMESPACE = "pasqal" -# Brand palette. Keys use the uniform _ form (see module docstring). +# Brand palette, keyed by _. The underscore keeps these from +# colliding with any Matplotlib built-in color name. PALETTE: Mapping[str, str] = { "metal_blue": "#397378", "neon_purple": "#867BFA", @@ -40,9 +40,9 @@ "neutral_gray": "#506166", } -# Colormaps map to palette keys, interpolated in order. Diverging maps go -# ->
-> ; the plain name uses the near-white center, the -# _dark variant the near-black one. +# Colormaps are palette keys interpolated in order. Diverging maps go +# ->
-> : the plain name uses a near-white center, the +# _dark variant a near-black one. DIVERGING: Mapping[str, Sequence[str]] = { "qq_purple_mint": ("neon_purple", "bright_green", "mint_green"), "qq_purple_mint_dark": ("neon_purple", "dark_green", "mint_green"), @@ -79,18 +79,19 @@ def _build_colormaps() -> dict[str, LinearSegmentedColormap]: def register(bare: bool = True) -> None: """Register the brand colors and colormaps with Matplotlib. - Called automatically on import. + Called automatically on import; idempotent. Args: bare: Also register the palette under its plain keys (``"mint_green"``) - in addition to the namespaced ones (``"pasqal:mint_green"``). Safe - because underscore names cannot collide with Matplotlib built-ins. + alongside the namespaced ones (``"pasqal:mint_green"``). """ names = {f"{NAMESPACE}:{key}": value for key, value in PALETTE.items()} if bare: names.update(PALETTE) mpl.colors.get_named_colors_mapping().update(names) + # Skip names already present so repeated imports never clobber an existing + # colormap registered under the same name. for name, cmap in COLORMAPS.items(): try: # Matplotlib >= 3.6 if name not in mpl.colormaps: @@ -101,4 +102,5 @@ def register(bare: bool = True) -> None: except ValueError: # already registered pass + register() From 935045f042c4399cfc234c4c3588164afbfc0ba8 Mon Sep 17 00:00:00 2001 From: Alessandro Santini Date: Tue, 4 Aug 2026 16:54:21 +0200 Subject: [PATCH 3/6] simplified --- qoolqit/utils/colors.py | 52 +++++++++++++++++------------------------ 1 file changed, 21 insertions(+), 31 deletions(-) diff --git a/qoolqit/utils/colors.py b/qoolqit/utils/colors.py index 290ceb792..65f1964c0 100644 --- a/qoolqit/utils/colors.py +++ b/qoolqit/utils/colors.py @@ -1,17 +1,16 @@ """PASQAL/QoolQit brand colors and colormaps for Matplotlib. Importing this module registers extra names with Matplotlib; it never touches -``rcParams``, so existing plots are unaffected. Colors are registered both bare -(``"mint_green"``) and namespaced (``"pasqal:mint_green"``). Colormaps follow -``qq__`` (diverging) and ``qq_`` (sequential), each also -available reversed with the usual ``_r`` suffix. +``rcParams``, so existing plots are unaffected. Palette entries become named +colors (``"mint_green"``) and colormaps follow ``_`` (diverging) and +```` (sequential), each also available reversed with the usual ``_r`` +suffix. Examples: >>> import matplotlib.pyplot as plt >>> from qoolqit.utils import colors - >>> plt.plot(x, y, color="mint_green") # bare name - >>> plt.plot(x, y, color="pasqal:mint_green") # namespaced (same color) - >>> plt.imshow(data, cmap="qq_purple_mint") + >>> plt.plot(x, y, color="mint_green") + >>> plt.imshow(data, cmap="purple_mint") """ from __future__ import annotations @@ -24,8 +23,6 @@ __all__ = ["PALETTE", "DIVERGING", "SEQUENTIAL", "COLORMAPS"] -NAMESPACE = "pasqal" - # Brand palette, keyed by _. The underscore keeps these from # colliding with any Matplotlib built-in color name. PALETTE: Mapping[str, str] = { @@ -44,22 +41,22 @@ # ->
-> : the plain name uses a near-white center, the # _dark variant a near-black one. DIVERGING: Mapping[str, Sequence[str]] = { - "qq_purple_mint": ("neon_purple", "bright_green", "mint_green"), - "qq_purple_mint_dark": ("neon_purple", "dark_green", "mint_green"), - "qq_orange_mint": ("soft_orange", "bright_green", "mint_green"), - "qq_orange_mint_dark": ("soft_orange", "dark_green", "mint_green"), - "qq_purple_orange": ("neon_purple", "bright_green", "soft_orange"), - "qq_purple_orange_dark": ("neon_purple", "dark_green", "soft_orange"), - "qq_blue_mint": ("neon_blue", "bright_green", "mint_green"), - "qq_blue_mint_dark": ("neon_blue", "dark_green", "mint_green"), + "purple_mint": ("neon_purple", "bright_green", "mint_green"), + "purple_mint_dark": ("neon_purple", "dark_green", "mint_green"), + "orange_mint": ("soft_orange", "bright_green", "mint_green"), + "orange_mint_dark": ("soft_orange", "dark_green", "mint_green"), + "purple_orange": ("neon_purple", "bright_green", "soft_orange"), + "purple_orange_dark": ("neon_purple", "dark_green", "soft_orange"), + "blue_mint": ("neon_blue", "bright_green", "mint_green"), + "blue_mint_dark": ("neon_blue", "dark_green", "mint_green"), } SEQUENTIAL: Mapping[str, Sequence[str]] = { - "qq_mint": ("bright_green", "mint_green"), - "qq_purple": ("bright_green", "neon_purple"), - "qq_orange": ("bright_green", "soft_orange"), - "qq_deep": ("bright_green", "mint_green", "metal_blue", "dark_green"), - "qq_night": ("dark_green", "metal_blue", "mint_green"), + "mint": ("bright_green", "mint_green"), + "purple": ("bright_green", "neon_purple"), + "orange": ("bright_green", "soft_orange"), + "deep": ("bright_green", "mint_green", "metal_blue", "dark_green"), + "night": ("dark_green", "metal_blue", "mint_green"), } @@ -76,19 +73,12 @@ def _build_colormaps() -> dict[str, LinearSegmentedColormap]: COLORMAPS: Mapping[str, LinearSegmentedColormap] = _build_colormaps() -def register(bare: bool = True) -> None: +def register() -> None: """Register the brand colors and colormaps with Matplotlib. Called automatically on import; idempotent. - - Args: - bare: Also register the palette under its plain keys (``"mint_green"``) - alongside the namespaced ones (``"pasqal:mint_green"``). """ - names = {f"{NAMESPACE}:{key}": value for key, value in PALETTE.items()} - if bare: - names.update(PALETTE) - mpl.colors.get_named_colors_mapping().update(names) + mpl.colors.get_named_colors_mapping().update(PALETTE) # Skip names already present so repeated imports never clobber an existing # colormap registered under the same name. From 3ec7d3c61bc249ac3e4866e76a6f54bb14546a26 Mon Sep 17 00:00:00 2001 From: Alessandro Santini Date: Tue, 4 Aug 2026 18:03:56 +0200 Subject: [PATCH 4/6] Simplified --- qoolqit/utils/colors.py | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/qoolqit/utils/colors.py b/qoolqit/utils/colors.py index 65f1964c0..cb354dc91 100644 --- a/qoolqit/utils/colors.py +++ b/qoolqit/utils/colors.py @@ -18,7 +18,6 @@ from collections.abc import Mapping, Sequence import matplotlib as mpl -import matplotlib.pyplot as plt from matplotlib.colors import LinearSegmentedColormap __all__ = ["PALETTE", "DIVERGING", "SEQUENTIAL", "COLORMAPS"] @@ -80,17 +79,9 @@ def register() -> None: """ mpl.colors.get_named_colors_mapping().update(PALETTE) - # Skip names already present so repeated imports never clobber an existing - # colormap registered under the same name. for name, cmap in COLORMAPS.items(): - try: # Matplotlib >= 3.6 - if name not in mpl.colormaps: - mpl.colormaps.register(cmap, name=name) - except AttributeError: # older Matplotlib - try: - plt.register_cmap(name=name, cmap=cmap) - except ValueError: # already registered - pass + if name not in mpl.colormaps: + mpl.colormaps.register(cmap, name=name) register() From 70c25e44475d614598a8ceb0d74216dea0da9096 Mon Sep 17 00:00:00 2001 From: Alessandro Santini Date: Wed, 5 Aug 2026 11:23:14 +0200 Subject: [PATCH 5/6] Renamed QoolQit Palette --- qoolqit/utils/colors.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/qoolqit/utils/colors.py b/qoolqit/utils/colors.py index cb354dc91..90079d084 100644 --- a/qoolqit/utils/colors.py +++ b/qoolqit/utils/colors.py @@ -1,4 +1,4 @@ -"""PASQAL/QoolQit brand colors and colormaps for Matplotlib. +"""QoolQit colors and colormaps for Matplotlib. Importing this module registers extra names with Matplotlib; it never touches ``rcParams``, so existing plots are unaffected. Palette entries become named @@ -22,7 +22,7 @@ __all__ = ["PALETTE", "DIVERGING", "SEQUENTIAL", "COLORMAPS"] -# Brand palette, keyed by _. The underscore keeps these from +# Qoolqit palette, keyed by _. The underscore keeps these from # colliding with any Matplotlib built-in color name. PALETTE: Mapping[str, str] = { "metal_blue": "#397378", @@ -60,7 +60,7 @@ def _build_colormaps() -> dict[str, LinearSegmentedColormap]: - """Build every brand colormap plus its reversed ``_r`` variant.""" + """Build every colormap plus its reversed ``_r`` variant.""" cmaps: dict[str, LinearSegmentedColormap] = {} for name, keys in {**DIVERGING, **SEQUENTIAL}.items(): cmaps[name] = LinearSegmentedColormap.from_list(name, [PALETTE[key] for key in keys]) @@ -73,7 +73,7 @@ def _build_colormaps() -> dict[str, LinearSegmentedColormap]: def register() -> None: - """Register the brand colors and colormaps with Matplotlib. + """Register the colors and colormaps with Matplotlib. Called automatically on import; idempotent. """ From e10802728dec9536d7b9385049feec7db3a826e4 Mon Sep 17 00:00:00 2001 From: Alessandro Santini <76155864+alessandro-santini@users.noreply.github.com> Date: Wed, 5 Aug 2026 11:26:22 +0200 Subject: [PATCH 6/6] Apply suggestion from @sgrava Co-authored-by: Stefano Grava <42062939+sgrava@users.noreply.github.com> --- qoolqit/__init__.py | 1 - 1 file changed, 1 deletion(-) diff --git a/qoolqit/__init__.py b/qoolqit/__init__.py index 270c948ce..cd11c0386 100644 --- a/qoolqit/__init__.py +++ b/qoolqit/__init__.py @@ -18,7 +18,6 @@ from qoolqit.execution.sequence_compiler import SequenceCompiler from qoolqit.program import QuantumProgram from qoolqit.register import Register -from qoolqit.utils import colors from qoolqit.waveforms import ( BlackmanWaveform, ConstantWaveform,