A set of useful perceptually uniform colormaps for plotting scientific data

Overview



Colorcet: Collection of perceptually uniform colormaps

Build Status Linux/MacOS Build Status
Coverage codecov
Latest dev release Github tag dev-site
Latest release Github release PyPI version colorcet version conda-forge version defaults version
Docs gh-pages site

What is it?

Colorcet is a collection of perceptually uniform colormaps for use with Python plotting programs like bokeh, matplotlib, holoviews, and datashader based on the set of perceptually uniform colormaps created by Peter Kovesi at the Center for Exploration Targeting.

Installation

Colorcet supports Python 2.7, 3.5, 3.6, 3.7, 3.8 and 3.9 on Linux, Windows, or Mac and can be installed with conda:

    conda install colorcet

or with pip:

    pip install colorcet

Once installed you can copy the examples into the current directory using the colorcet command and run them using the Jupyter notebook:

colorcet examples
cd colorcet-examples
jupyter notebook

(Here colorcet examples is a shorthand for colorcet copy-examples --path colorcet-examples && colorcet fetch-data --path colorcet-examples.)

To work with JupyterLab you will also need the PyViz JupyterLab extension:

conda install -c conda-forge jupyterlab
jupyter labextension install @pyviz/jupyterlab_pyviz

Once you have installed JupyterLab and the extension launch it with:

jupyter-lab

If you want to try out the latest features between releases, you can get the latest dev release by specifying -c pyviz/label/dev in place of -c pyviz.

For more information take a look at Getting Started.

Learning more

You can see all the details about the methods used to create these colormaps in Peter Kovesi's 2015 arXiv paper. Other useful background is available in a 1996 paper from IBM.

The Matplotlib project also has a number of relevant resources, including an excellent 2015 SciPy talk, the viscm tool for creating maps like the four in mpl, the cmocean site collecting a set of maps created by viscm, and the discussion of how the mpl maps were created.

Samples

All the Colorcet colormaps that have short, memorable names (which are probably the most useful ones) are visible here:

But the complete set of 50+ is shown in the User Guide.

Comments
  • Add Glasbey colors?

    Add Glasbey colors?

    Colorcet currently includes only continuous color spaces, but it was created while working on Datashader, which uses both continuous and categorical sets of colors. For rendering categorical data, Datashader requires having a distinct color per category, and it includes some ad-hoc collections of colors to try to get enough distinct colors to deal with complex datasets.

    A principled approach for designing arbitrarily large sets of mutually distinct colors was presented in:

    Glasbey, Chris; van der Heijden, Gerie & Toh, Vivian F. K. et al. (2007), "Colour displays for categorical images", Color Research & Application 32.4: 304-309.

    "Glasbey" colors are available in ImageJ and for R, and there is a Python implementation of the method. Generating the colors with the Python code is time consuming, so it would be convenient to generate one or more large sets of Glasbey colors and distribute them in colorcet.

    Here's an example of generating 257 colors, which took about 5 minutes to run:

    pip install colorspacious
    git clone https://github.com/taketwo/glasbey.git
    cd glasbey
    python glasbey.py --view 257 --format float output.csv
    

    image

    You can click on the image to see it in more detail. The resulting list of color triples can easily be added to colorcet:

    1.000000,1.000000,1.000000
    0.000000,0.000000,0.000000
    0.843137,0.000000,0.000000
    0.549020,0.235294,1.000000
    ...
    0.462745,0.160784,0.286275
    0.741176,0.898039,0.000000
    
    opened by jbednar 22
  • pyct dependency used inside setup.py

    pyct dependency used inside setup.py

    The pyct.build package is imported and used before setup is called and so a build from a fresh python environment fails because it can't import pyct.build as it hasn't yet been installed as a build dependency.

    opened by jsharpe 11
  • Simplify aliases and import new cmaps from Dec 2020

    Simplify aliases and import new cmaps from Dec 2020

    Summary

    In Dec. 2020 Peter updated the CET colormaps. This PR contains multiple changes:

    1. Change aliases to a dict of lists. This simplifies the logic of finding all the aliases for a given name and makes it easy to add aliases for a given map.
    2. Add new colormaps available in the Dec 2020 update to colorcet.m from Peter Kovesi, as well as at most one alias for any colormaps that do not yet have one.

    Notes

    • This PR depends on, and follows after, PR #64, which makes each colormap's algorithmic name AKA descriptorname the name of the CSV file.
    • Resolves #60
    • Resolves #56
    • Since the CET_ name may in some cases be the only alias to a map, I have not removed those, though we talked about it previously. (Actually, I did at first, but then reverted the change). If someone wants to do this it's pretty easy--just remove cetnames, cetnames_flipped, and anything that references those variables from CET_to_py.py, rerun CET_to_py.py and update the tests.
    • In this PR new colormap CSVs are not downloaded from Peter's site (as he doesn't have them all there anyway) but rather are generated from colorcet.m (using MATLAB/Octave script make_csvs_from_colorcet.m), since colorcet.m is the "upstream" of those CSVs. Some of the existing CSV colormaps in holoviz/colorcet don't exactly match what what's in colorcet.m but what's already here is being left as-is.
    • A few CSVs have been renamed or removed as duplicates of existing CSVs with the same colormap. All CET CSVs should now have the algorithmic name (e.g. linear_kbc_5_95_c73 instead of linear_blue_5_95_c73. The old names (..._blue_...) may still be used.
    • All existing aliases have been retained. New aliases have been added only for new colormaps or where aliases did not previously exist.
    • Instructions for merging future additions from colorcet.m are at the top of make_csvs_from_colorcet.m and CET_merge.py.
    opened by randallpittman 8
  • Resolve #60, #56 - Allow multiple aliases, update colormaps from colorcet.m (second attempt)

    Resolve #60, #56 - Allow multiple aliases, update colormaps from colorcet.m (second attempt)

    This is a second attempt at #62.

    • Resolves #60 by changing aliases in CET_to_py.py to a dict of lists. This renders aliases_v2 unnecessary. Minor changes necessary to make CET_to_py.py and then colorcet/__init__.py work with a dict of lists.
    • Resolves #56 by the scripts make_csvs_from_colorcet.m and CET_merge.py, along with instructions in README_assets.md. The scripts were used to generate new CSVs for new colormaps and update CET_to_py.py which in turn were used to update colorcet/__init__.py with the new colormaps and aliases.
    • aliases in CET_to_py.py is now a dict of lists. This renders the aliases_v2 dict unnecessary, as those can be added in to aliases as additional values.
    • Ultimately I made sure that no existing colormaps or aliases are overridden but do allow for new aliases for existing colormap (e.g. "heat" == "fire", "gray" == "gray", etc.). Tests check out, and swatches look good in the example notebooks. This took a few iterations to figure out programmatically in CET_merge.py but I think I finally got it right.
    • New maps are in assets/CETperceptual_csv_0_1_v3. It looked like for each existing cyclical colormap there was also one with 0.25 shift so I followed suit and included similarly-shifted maps along with the non-shifted maps (e.g. CET-C7s etc.)
    • I think examples/assets/images/named.png needs to be updated, but I couldn't get examples/assets/write_named.py to run right on my machine. I got these warnings and the maps didn't plot right at all:
      WARNING:bokeh.io.export:There were browser warnings and/or errors that may have affected your export
      WARNING:bokeh.io.export:http://localhost:5006/static/extensions/panel/css/json.css - Failed to load resource: net::ERR_CONNECTION_REFUSED
      WARNING:bokeh.io.export:http://localhost:5006/static/extensions/panel/css/widgets.css - Failed to load resource: net::ERR_CONNECTION_REFUSED
      WARNING:bokeh.io.export:http://localhost:5006/static/extensions/panel/css/alerts.css - Failed to load resource: net::ERR_CONNECTION_REFUSED
      WARNING:bokeh.io.export:http://localhost:5006/static/extensions/panel/css/markdown.css - Failed to load resource: net::ERR_CONNECTION_REFUSED
      WARNING:bokeh.io.export:http://localhost:5006/static/extensions/panel/css/dataframe.css - Failed to load resource: net::ERR_CONNECTION_REFUSED
      WARNING:bokeh.io.export:http://localhost:5006/static/extensions/panel/css/card.css - Failed to load resource: net::ERR_CONNECTION_REFUSED
      

      It should be stated that I'm not a user of holoviews or bokeh, so I might have something set up wrong.

    • I reworked get_aliases() a bit to just keep trying to get more aliases until no more are found. I hope the result is OK in terms of the order of results returned. I reworked test_get_aliases() to use sets and therefore not care about the order of the maps returned by get_aliases().
    • Conflict output of CET_merge.py showing old aliases and mappings retained that are different from colorcet.m:
      #
      # ## NOTICE: Found the following aliases conflicts, with old alias assignment retained over new:
      # ## alias, old_descriptorname, new_descriptorname
      # bgyw, linear_bgyw_15_100_c68, linear_bgyw_20_98_c66
      # bmw, linear_bmw_5_95_c89, linear_bmw_5_95_c86
      # bmy, linear_bmy_10_95_c78, linear_bmy_10_95_c71
      # kbc, linear_blue_5_95_c73, linear_kbc_5_95_c73
      # kgy, linear_green_5_95_c69, linear_kgy_5_95_c69
      # rainbow, rainbow_bgyr_35_85_c73, rainbow_bgyrm_35_85_c69
      #
      # ## NOTICE: Found the following mapping conflicts, with the CET- name assigned
      # ##         to the original map over the new:
      # ## CET_name, old_descriptorname, new_descriptorname
      # CET-L16, linear_kbgyw_5_98_c62, linear_kbgyw_10_98_c63
      #
      
    opened by randallpittman 8
  • ValueError: A colormap named

    ValueError: A colormap named "cet_gray" is already registered

    ALL software version info

    colorcet 3.0.1 arviz 0.12.1 python 3.10/8 matplotlib 3.6.0/1 afaik introduced with recent colorcet/matplotlib release

    Description of expected behavior and the observed behavior

    When multiple libraries use mpl.colormaps.register(cmap, name=cmap_name) with the same cmap_name, a ValueError: A colormap named "cet_gray" is already registered. is raised. This happens e.g. for colorcet + arviz, both of which define cet_gray (see here for arviz).

    What is the desired behavior -- does colorcet want to assume control of that color name, preventing others from accidentally overriding it (in which case arviz, which intends to duplicate the colorcet color, would be responsible)? Or should simultaneous overriding of the global variable be allowed.

    Complete, minimal, self-contained example code that reproduces the issue

    import arviz
    import colorcet
    

    or

    import colorcet
    import arviz
    

    This prohibits the use of both simultaneously.

    Stack traceback and/or browser JavaScript console output

    Traceback (most recent call last):
     File "<string>", line 1, in <module>
     File "/home/yannik/env/env/lib/python3.10/site-packages/arviz/__init__.py", line 320, in <module>
       _mpl_cm("gray", _linear_grey_10_95_c0)
     File "/home/yannik/env/env/lib/python3.10/site-packages/arviz/__init__.py", line 317, in _mpl_cm
       register_cmap("cet_" + name, cmap=cmap)
     File "/home/yannik/env/env/lib/python3.10/site-packages/matplotlib/_api/deprecation.py", line 200, in wrapper
       return func(*args, **kwargs)
     File "/home/yannik/env/env/lib/python3.10/site-packages/matplotlib/cm.py", line 248, in register_cmap
       _colormaps.register(cmap, name=name, force=override_builtin)
     File "/home/yannik/env/env/lib/python3.10/site-packages/matplotlib/cm.py", line 149, in register
       raise ValueError(
    ValueError: A colormap named "cet_gray" is already registered.
    
    opened by yannikschaelte 7
  • pytest on gh actions

    pytest on gh actions

    @jbednar @philippjfr I could use some feedback on this PR. I believe pytest was only run on Linux 3.7. I've opened it up to all platforms/versions so its possible that some of these are known issues that I should avoid.

    Current status:
    Python 3.6 - PASS
    Python 3.7 - PASS

    Python 2.7, Ubuntu
    Some failures looking for DISPLAY env var: Invalid DISPLAY variable  https://github.com/kcpevey/colorcet/pull/1/checks?check_run_id=2042433951#step:9:489 Which I could set... but if you look at the code block where the failure is, its thinking that the ubuntu 2.7 build is X11 and its part of a qt5 backend. Which just seems wrong is several different ways. Should I just set the variable it wants or dig into why its getting there in the first place?

    I see this failure on all 2.7 architectures https://github.com/kcpevey/colorcet/pull/1/checks?check_run_id=2042433951#step:9:502 Seems like the codebase is not actually supported on 2.7? It would be an easy fix to swap these around though. Should add that in as well?

    For python 3.5 I'm seeing this:

    
      target environment location: C:\Miniconda3\envs\colorcet
      current conda version: 4.5.11
      minimum conda version: 4.9
    

    I did some initial googling about this, but I haven't worked out a solution (or what the problem is, actually). 

    opened by kcpevey 5
  • PyPI release of 1.0.0

    PyPI release of 1.0.0

    Would be great to have an sdist on PyPI for the 1.0.0 release. This should help move packaging in conda-forge forward.

    xref: https://github.com/conda-forge/staged-recipes/issues/4029

    opened by jakirkham 5
  • tab-completion for interactivity?

    tab-completion for interactivity?

    This is a usability question. It looks to me like all the colormaps are available via the cc.cm dictionary. However, there is no auto-complete for dictionaries in jupyter notebook, so I either need to remember the name exactly and type it out, or call cm.keys(), search for the colormap, and copy and paste the string.

    Maybe there's an easier way that I don't see?

    If I could use jupyters auto-complete to find the right color map, that would be much easier given your naming schemes. One way to achieve that would be to make cm be a bunch object, so that the items can be obtained with __get_attr__. If you define __dir__ right, that allows tab-completion. You could also define a sub-module that has instances of the colormaps with appropriate names (I think that's what matplotlib does?)

    Thanks for these great colormaps!

    opened by amueller 5
  • Update links and text to point to holoviz.org

    Update links and text to point to holoviz.org

    The string 'pyviz' appears in a few places in the code but I don't intend to update those just yet (e.g for the conda channel). Some of the text in the README about HoloViz/PyViz should also appear on the website but that is for a separate PR.

    opened by jlstevens 4
  • Adding glasbey colormaps

    Adding glasbey colormaps

    Adding glasbey colors according to a new naming pattern with aliases for Category, Category10, and Category20.

    To Do:

    • [x] add assets
    • [x] add to module
    • [x] write tests
    • [x] write up docs
    • [x] add an example

    Closes: #11

    opened by jsignell 4
  • Restructuring to get Chris' branch working

    Restructuring to get Chris' branch working

    • Took out command line tool
    • Restructuring docs to incorporate content from README
    • Moving dependencies from setup.cfg to setup.py
    • Adding some unit tests
    opened by jsignell 4
  • [Improvement] Asymmetric colormaps

    [Improvement] Asymmetric colormaps

    Hello,

    Would be very useful to have a built in function that returns asymmetric colormaps. Something that would take a min, a max, and a center, and would return a colormap that conforms to that. This would be useful when the aim is for the colormap to be centered about 0.

    enhancement 
    opened by cristi-neagu 5
Releases(v3.0.1)
  • v3.0.1(Oct 3, 2022)

    Minor release to improve compatibility with the Python ecosystem and remove deprecation warnings. Thanks to Kian-Meng Ang for docs and instructions fixes, Maxime Liquet for CI and docs fixes, and to Jim Bednar for docs updates, compatibility fixes, and coordinating the release.

    • Update to work with matplotlib=3.6 (#90)
    • Fix holoviews opts deprecation warning (#94)
    • Add support for Python 3.10 (#81)
    • Remove windows 3.6 case from test suite due to lack of mamba support (#94)
    • Remove Param dependency (#84)
    • Improve installation instructions (#92)
    Source code(tar.gz)
    Source code(zip)
  • v3.0.0(Nov 28, 2021)

    Major new release adding 23 new continuous colormaps from Peter Kovesi's upstream colorcet.m. The existing colormaps should all have the same names and values as in previous releases, and apart from a minor change to the type of Matplotlib categorical colormaps this release should be fully backwards compatible with previous releases.

    Thanks to Randy Pittman for major improvements to the automated colormap definition code that allowed bringing in the new colormaps, to Maxime Liquet for CI and website fixes, and to Jim Bednar for docs updates, compatibility fixes, and coordinating the release.

    New features:

    • Added new upstream colormaps (#65):
      • Rainbow: rainbow_bgyr_10_90_c83 (called rainbow4, a much closer match to Jet's color range than rainbow while remaining perceptually uniform)
      • Linear: linear_kbgoy_20_95_c57 (called gouldian, an improved version of Matlab's parula colormap), linear_kbgyw_10_98_c63
      • Cyclic: circle_mgbm_67_c31, circle_mgbm_67_c31_s25, cyclic_bgrmb_35_70_c75, cyclic_bgrmb_35_70_c75_s25, cyclic_isoluminant, cyclic_mybm_20_100_c48, cyclic_mybm_20_100_c48_s25, cyclic_mygbm_50_90_c46, cyclic_mygbm_50_90_c46_s25, cyclic_rygcbmr_50_90_c64, cyclic_rygcbmr_50_90_c64_s25, cyclic_wrkbw_10_90_c43, cyclic_wrkbw_10_90_c43_s25, cyclic_ymcgy_60_90_c67, cyclic_ymcgy_60_90_c67_s25
      • Colorblind-safe: diverging_linear_protanopic_deuteranopic_bjy_57_89_c34, linear_protanopic_deuteranopic_kbw_5_95_c34, linear_protanopic_deuteranopic_kyw_5_95_c49, linear_tritanopic_kcw_5_95_c22, linear_tritanopic_krw_5_95_c46
    • CI fixes and improvements, including testing for python 3.9 (#71, #72, #75, #77)
    • Clarified docs to indicate that all maps have an original list-of-numeric-triples form, typically but not always with a long name, that all those starting with b_ are Bokeh colormaps in hex format, and that only the subset of shorter names that are aliases for longer names are Bokeh colormaps (as some other original list names like glasbey_bw just happen to be short (#79)

    Compatibility:

    • For categorical (Glasbey) maps, now uses a Matplotlib ListedColormap (with distinct colors) instead of a LinearSegmentedColormap (discrete approximation to a continuous map) (#79)
    Source code(tar.gz)
    Source code(zip)
  • v2.0.5(Jan 19, 2021)

    Minor release primarily to update PyPI classifier to show that the license is not proprietary. Also added some docstrings and usage examples, and updated the swatch function to work with both list and tuple colormaps.

    Source code(tar.gz)
    Source code(zip)
  • v2.0.2(Jul 3, 2020)

  • v2.0.1(Apr 3, 2019)

  • v2.0.0(Apr 3, 2019)

    Major release adding perceptually based categorical colormaps, complementing the previous perceptually based continuous colormaps:

    • Added Glasbey 256-color categorical colormaps (#25)
    • Adding new continuous colormaps from CET (#26)
    • Added console script and docs to make it easy to run examples (#23)
    • Added colormap plotting commands in plotting.py (#25)
    Source code(tar.gz)
    Source code(zip)
  • v1.0.1(Feb 14, 2019)

    Infrastructure update:

    • Added travis and appveyor
    • Switched to using nbsite, pyct.build, pyctdev,

    Docs update:

    • Migrated README content to docs
    • Added usage section

    Full list of changes since the previous release: https://github.com/pyviz/colorcet/compare/v1.0.0...v1.0.1

    Source code(tar.gz)
    Source code(zip)
  • v1.0.0(Sep 26, 2017)

    Minor update improving compatibility and ease of use:

    • Added attribute access for colormap and palette dictionaries for convenience (PR #5)
    • Pulled out the subset of colormaps that have readable names into the cm_n and palette_n dictionaries to make it simpler to use them in GUI widgets selecting colormaps
    • Improved Python2/Python3 compatibility, now supporting Python 2.7, 3.4, 3.5, and 3.6.

    Minor backwards compatibility issue:

    • Renamed inferno to bmy to avoid confusion with matplotlib.
    Source code(tar.gz)
    Source code(zip)
  • 0.9.1(Dec 14, 2016)

  • 0.9.0(Nov 8, 2016)

Owner
HoloViz
High-level tools to simplify visualization in Python
HoloViz
This GitHub Repository contains Data Analysis projects that I have completed so far! While most of th project are focused on Data Analysis, some of them are also put here to show off other skills that I have learned.

Welcome to my Data Analysis projects page! This GitHub Repository contains Data Analysis projects that I have completed so far! While most of th proje

Kyle Dini 1 Jan 31, 2022
Python Data. Leaflet.js Maps.

folium Python Data, Leaflet.js Maps folium builds on the data wrangling strengths of the Python ecosystem and the mapping strengths of the Leaflet.js

6k Jan 02, 2023
basemap - Plot on map projections (with coastlines and political boundaries) using matplotlib.

Basemap Plot on map projections (with coastlines and political boundaries) using matplotlib. ⚠️ Warning: this package is being deprecated in favour of

Matplotlib Developers 706 Dec 28, 2022
Make scripted visualizations in blender

Scripted visualizations in blender The goal of this project is to script 3D scientific visualizations using blender. To achieve this, we aim to bring

Praneeth Namburi 10 Jun 01, 2022
Using SQLite within Python to create database and analyze Starcraft 2 units data (Pandas also used)

SQLite python Starcraft 2 English This project shows the usage of SQLite with python. To create, modify and communicate with the SQLite database from

1 Dec 30, 2021
Here are my graphs for hw_02

Let's Have A Look At Some Graphs! Graph 1: State Mentions in Congressperson's Tweets on 10/01/2017 The graph below uses this data set to demonstrate h

7 Sep 02, 2022
A small script written in Python3 that generates a visual representation of the Mandelbrot set.

Mandelbrot Set Generator A small script written in Python3 that generates a visual representation of the Mandelbrot set. Abstract The colors in the ou

1 Dec 28, 2021
This is a super simple visualization toolbox (script) for transformer attention visualization ✌

Trans_attention_vis This is a super simple visualization toolbox (script) for transformer attention visualization ✌ 1. How to prepare your attention m

Mingyu Wang 3 Jul 09, 2022
Learning Convolutional Neural Networks with Interactive Visualization.

CNN Explainer An interactive visualization system designed to help non-experts learn about Convolutional Neural Networks (CNNs) For more information,

Polo Club of Data Science 6.3k Jan 01, 2023
Create Badges with stats of Scratch User, Project and Studio. Use those badges in Github readmes, etc.

Scratch-Stats-Badge Create customized Badges with stats of Scratch User, Studio or Project. Use those badges in Github readmes, etc. Examples Document

Siddhesh Chavan 5 Aug 28, 2022
https://there.oughta.be/a/macro-keyboard

inkkeys Details and instructions can be found on https://there.oughta.be/a/macro-keyboard In contrast to most of my other projects, I decided to put t

Sebastian Staacks 209 Dec 21, 2022
Tools for writing, submitting, debugging, and monitoring Storm topologies in pure Python

Petrel Tools for writing, submitting, debugging, and monitoring Storm topologies in pure Python. NOTE: The base Storm package provides storm.py, which

AirSage 247 Dec 18, 2021
A pandas extension that solves all problems of Jalai/Iraninan/Shamsi dates

Jalali Pandas Extentsion A pandas extension that solves all problems of Jalai/Iraninan/Shamsi dates Features Series Extenstion Convert string to Jalal

51 Jan 02, 2023
A Python library created to assist programmers with complex mathematical functions

libmaths was created not only as a learning experience for me, but as a way to make mathematical models in seconds for Python users using mat

Simple 73 Oct 02, 2022
The interactive graphing library for Python (includes Plotly Express) :sparkles:

plotly.py Latest Release User forum PyPI Downloads License Data Science Workspaces Our recommended IDE for Plotly’s Python graphing library is Dash En

Plotly 12.7k Jan 05, 2023
Visualize tensors in a plain Python REPL using Sparklines

Visualize tensors in a plain Python REPL using Sparklines

Shawn Presser 43 Sep 03, 2022
Python library that makes it easy for data scientists to create charts.

Chartify Chartify is a Python library that makes it easy for data scientists to create charts. Why use Chartify? Consistent input data format: Spend l

Spotify 3.2k Jan 04, 2023
Visualise top-rated GitHub repositories in a barchart by keyword

This python script was written for simple purpose -- to visualise top-rated GitHub repositories in a barchart by keyword. Script generates html-page with barchart and information about repository own

Cur1iosity 2 Feb 07, 2022
Small binja plugin to import header file to types

binja-import-header (v1.0.0) Author: matteyeux Import header file to Binary Ninja types view Description: Binary Ninja plugin to import types from C h

matteyeux 15 Dec 10, 2022
Generate SVG (dark/light) images visualizing (private/public) GitHub repo statistics for profile/website.

Generate daily updated visualizations of GitHub user and repository statistics from the GitHub API using GitHub Actions for any combination of private and public repositories, whether owned or contri

Adam Ross 2 Dec 16, 2022