Skip to content

fix: move Tableau colormaps to their own namespace, fix catalog metadata - #166

Merged
tlambert03 merged 4 commits into
pyapp-kit:mainfrom
tlambert03:fix/catalog-metadata
Oct 19, 2026
Merged

tlambert03 merged 4 commits into
pyapp-kit:mainfrom
tlambert03:fix/catalog-metadata

Conversation

@tlambert03

@tlambert03 tlambert03 commented Oct 19, 2026 •

Copy link
Copy Markdown
Member

The tableau colormaps (tab10, tab20, etc) have been living in the seaborn namespace this whole time. Turns out that was just a copy-paste error from when I converted the data modules to record.json files in 6410b81... tableau/record.json copied its info, license and namespace from seaborn/record.json, which was itself still a placeholder template ("info": "This is a test dataset", "authors": ["John Doe"] 😂). The authors and source were already Tableau's. The old _tableau.py it replaced had nothing to do with seaborn (it said __license__ = "UNKNOWN"). The only real connection is that seaborn's default palettes are variations on matplotlib's tab10.

This came up while building per-collection pages for the new docs (#165), where all of that placeholder stuff was suddenly very visible.

  • tableau maps are now tableau:*. The old seaborn:tab* names are kept as aliases, so nothing breaks, and plain tab10 etc. still resolve to the same colors.
  • each Tableau palette gets an info, and I only attributed what Tableau's own sources back up: Maureen Stone designed the basic palettes in 2004 for Tableau 1.5 (her bio), tab10_new is the 2016 "Tableau 10" redesign by Stone and Cristy Miller, and Tableau 20 is light/dark pairs of the Tableau 10 hues (blog post). The post also says they redesigned all of the old palettes for Tableau 10, so for Color Blind 10, Traffic Light and Tableau 10 Light/Medium I don't know which version we have, and the descriptions just name them (and they no longer list authors).
  • tab20b/tab20c are described as d3's category20b/category20c (which is also what matplotlib's tab20b/tab20c are, "from Vega"). I couldn't find who designed those.
  • the tableau license was BSD-3-Clause (copied from seaborn, and also in REUSE.toml). As far as I can tell Tableau has never published a license for these, so it's UNKNOWN, and REUSE.toml now treats it like okabeito and matlab.
  • the source URL now points at where it redirects to (it's Chris Gerrard's Tableau Public workbook of the palettes, not something from Tableau itself).
  • seaborn: real author and description.
  • cmocean, cubehelix: their authors were [""].
  • ibm, paraview, petroff: were missing licenses. Filled in from upstream, which also matches what REUSE.toml already said (Petroff's color cycles are CC0 per his repo).

Two small catalog fixes were needed for the aliases. Since the seaborn record loads before the tableau one, tab10 ended up registered as conflicting with... itself, and plain Colormap("tab10") would log the "is also available as" warning. A short name that's already an alias for the same colormap is no longer counted as a conflict. And an alias's short and namespaced names no longer share one dict (otherwise a future conflict on tab10 would also show up on seaborn:tab10).

fwiw, one user-visible change: Colormap("tab10").name (and so repr, as_dict(), pydantic serialization, etc) is now "tableau:tab10" rather than "seaborn:tab10". Anything saved with the old name still loads, but something saved with this version won't load in an older cmap.

Not touched here: a couple of the color values differ by 1 in a channel from other sources. tab10_colorblind[1] is #FF8000 here vs #FF800E in matplotlib's tableau-colorblind10 style, and tab10_new has #F28E2B/#59A14E where d3's schemeTableau10 has #F28E2C/#59A14F (hence "nearly identical to" in the descriptions). I couldn't find anything authoritative from Tableau to say which is right (the blog post only shows them as images), so I left the data alone.

🤖 Generated with Claude Code

- tableau colormaps were mistakenly in the 'seaborn' namespace (a copy-paste
  of the seaborn record, including its placeholder info); they're now
  'tableau:*', and the old 'seaborn:tab*' names still work as aliases
- describe each Tableau palette and where it comes from; tab20b/tab20c are
  d3's, not Tableau's
- seaborn: real author and description instead of placeholders
- cmocean, cubehelix: fill in empty authors
- ibm, paraview, petroff: add their licenses (matching REUSE.toml / upstream)
- catalog: a short name that's already an alias for the same colormap is not
  a conflict

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@codecov

codecov Bot commented Oct 19, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 94.62%. Comparing base (87b7250) to head (b4c4762).

Additional details and impacted files
@@           Coverage Diff           @@
##             main     #166   +/-   ##
=======================================
  Coverage   94.62%   94.62%           
=======================================
  Files         168      168           
  Lines        2231     2232    +1     
=======================================
+ Hits         2111     2112    +1     
  Misses        120      120           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

tlambert03 and others added 3 commits October 19, 2026 12:01
Only the Tableau 10 / Tableau 20 attributions are backed by Tableau's own
sources; all of Tableau's palettes were redesigned in Tableau 10 (2016), so
it's not known which version the others are.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- REUSE.toml: drop the BSD-3-Clause override for tableau (no known license)
- per-colormap tableau authors (only where known); 2004 is when the palettes
  were designed, not when Tableau 1.5 shipped; 'nearly identical to' where the
  d3/matplotlib values differ slightly
- test that actually catches the alias self-conflict (it's logged, not warned)
- don't share one dict between an alias's short and namespaced names

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@tlambert03
tlambert03 merged commit ea766cf into pyapp-kit:main Oct 19, 2026
24 checks passed
@tlambert03
tlambert03 deleted the fix/catalog-metadata branch October 19, 2026 11:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant