Skip to content

feat!: compatibility with matplotlib 3.11 - #128

Open
miloth wants to merge 23 commits into
catppuccin:mainfrom
miloth:main
Open

miloth wants to merge 23 commits into
catppuccin:mainfrom
miloth:main

Conversation

@miloth

@miloth miloth commented Jun 28, 2026

Copy link
Copy Markdown
Contributor

Matplotlib 3.11 reworked the style module, changing the APIs that were used here. This aims at solving that and a bit more:

  • Vendor the styles using the docs guidelines:
    • Style files generated in the module root, so they can be imported as "catppuccin.<flavor>".
    • Removed legacy vendoring.
  • Removed all the public functions in the catppuccin.extras.matplotlib module. Their functionality can be replicated with a one liner of Matplotlib's APIs. All the examples now use these one liners.
  • Removed the assets and their generation. The users can run the example themselves to generate them. They were ~2 MB images, not used anywhere. I think these could pollute the git size if left there.
  • Helper file for the codegen moved outside of the module in the repo root, so it is not shipped to Pypi.
  • Update tests to cover the cmaps as well.
  • Updated cmaps to be colored and not mono.
  • Updated palette from upstream.
  • Updated dev dependencies.

@backwardspy

Copy link
Copy Markdown
Member

@brambozz any chance you could give this a review? you know it better than i do i think :)

@brambozz

Copy link
Copy Markdown
Collaborator

Yes, I will try to have a look this week!

@brambozz

Copy link
Copy Markdown
Collaborator

@miloth Thanks for the comprehensive PR, overall looks good to me! Especially really like the addition of a default (non-mono) colormap! That makes a lot of sense, and is something I could have used for a while.

Only thing I am not a fan of is the removal of the get_colormap_from_list function, in lieu of the matplotlib one-liner. This is a function I actually use frequently, to e.g. easily define a diverging colormap. While I understand that this is maybe not a functionality unique to catppuccin, I do think there is a difference in ease of use/clarity between these two:

Original:

from catppuccin.extras.matplotlib import get_colormap_from_list

cmap = get_colormap_from_list(
       catppuccin.PALETTE.frappe.identifier,
       ["red", "peach", "yellow", "green"],
)

PR suggestion:

from matplotlib.colors import LinearSegmentedColormap

cmap = LinearSegmentedColormap.from_list(
    "my_custom_palette",
    [
        getattr(catppuccin.PALETTE.frappe.colors, color_name).hex
        for color_name in ["red", "peach", "yellow", "green"]
    ],
)

@backwardspy:I think it would be good if you have a quick look too, as there are some changes to files I did not write (e.g. build.py). But looks good to me! One specific thing I spotted:

  • The PR upgrades minimum versions of python and matplotlib to 3.11. Seems fine to me, but maybe this is something you have thoughts about. The PR also goes from 2.5 to 3.0, so would amount to a new release.

@miloth

miloth commented Aug 3, 2026

Copy link
Copy Markdown
Contributor Author

Hi @brambozz, please find the replies below:

  • Removal of less common matplotlib APIs. This was intentional. I had a look at some PRs in their repo and it is fairly common to remove or change public APIs without a major bump. This got me thinking about what the purpose of this package should be. Is it intended to provide the user with palette for the four flavors, or to be a plotting library with added functionality? Given the versioning of matplotlib, I thought the first option would be better and easier to maintain. All at very limited cost, since it's fairly easy to define these from the matplotlib APIs. Btw, I edited the cmap call in the example you mentioned. Now it's much cleaner.
  • The 3.11 requirement is where matplotlib dropped their APIs used by this repo (and other similar plotting tools). I believe the major bump is recommended here, as this completely overhauls the calls.

@brambozz

brambozz commented Aug 7, 2026

Copy link
Copy Markdown
Collaborator

@miloth Thanks for the update! You have me convinced, it is probably indeed cleaner and more appropriate here to keep the API minimal.

Also the reasoning for the versioning is fine with me, but still something I would like to give @backwardspy the final word on.

So @backwardspy: For me it's all good now! But my earlier suggestion of you having a quick look still stands :)

@backwardspy backwardspy left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks for your patience on this, i've got a lot going on at the moment.

got a few comments/suggestions, let me know if anything's wrong or doesn't make sense.

a couple of other general things:

  • dropping support for python 3.9 and 3.10 is fine by me given 3.10 is almost EOL. would you mind updating the github actions workflows to only test against 3.11+ as well?
  • i think the DPI constant in build.py is dead now, looks like its only references were removed in this PR.

cheers!

_palette.identifier,
[
color.hex
for color in PALETTE.frappe.colors

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should this be _palette.colors instead?

Suggested change
for color in PALETTE.frappe.colors
for color in _palette.colors

[
color.hex
for color in PALETTE.frappe.colors
if color.identifier in ("blue", "teal", "yellow", "peach", "red")

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this looks like it should reference DEFAULT_COLORMAP_COLORS

Suggested change
if color.identifier in ("blue", "teal", "yellow", "peach", "red")
if color.identifier in DEFAULT_COLORMAP_COLORS

Comment thread pyproject.toml
dependencies = []
name = "catppuccin"
version = "2.5.0"
version = "3.0.0"

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please revert this one, release-please will handle the versioning for us :)

Suggested change
version = "3.0.0"
version = "2.5.0"

Comment thread catppuccin/models.py
Comment on lines +170 to +179
@property
def matplotlib_style(self) -> str:
"""Name of the matplotlib style associated with the flavor."""
return f"catppuccin.{self.identifier}"

@property
def cmap(self) -> str:
"""Name of the matplotlib colormap associated with the flavor."""
return self.identifier

@backwardspy backwardspy Sep 13, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i would prefer these to live inside the matplotlib extra if possible.

i think there's a case for just removing cmap; relying on identifier directly does introduce a little bit of coupling, but having this here just couples it the other way around (i.e. now the Flavor model has to know about matplotlib concepts.)

as for matplotlib_style, i'm not convinced it's that useful, but there's no harm keeping a helper for it. we could go with a style_name function inside catppuccin/extras/matplotlib.py along the lines of the following:

def style_name(flavor: Flavor) -> str:
    return f"catppuccin.{flavor.identifier}"

these are arguable stylistic choices, albeit ones motivated by keeping the main module clear of optional extras, but i'm open to debate on them. please let me know if you think changing them is a bad idea or you have a better way to approach it.

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.

3 participants