Create colormaps from images
======== img2cmap ========
Usage =====
Create colormaps from images in three lines of code!
| First, `ImageConverter class converts images to arrays of RGB values. | Then, generatecmap creates a matplotlib ListedColormap .
.. code-block:: python3
from img2cmap import ImageConverter
# Can be a local file or URL converter = ImageConverter("tests/images/southbeachsunset.jpg") cmap = converter.generatecmap(ncolors=5, palettename="southbeachsunset", randomstate=42)
Now, use the colormap in your plots!
.. code-block:: python3
import matplotlib.pyplot as plt
colors = cmap.colors
with plt.style.context("dark_background"): for i, color in enumerate(colors): plt.plot(range(10), [+i+1 for in range(10)], color=color, linewidth=4)
.. image:: images/img2cmap_demo.png :align: center
Plot the image and a colorbar side by side.
.. code-block:: python3
import matplotlib.pyplot as plt from mpltoolkits.axesgrid1 import makeaxeslocatable
fig, ax = plt.subplots(figsize=(7, 5))
ax.axis("off") img = plt.imread("tests/images/southbeachsunset.jpg") im = ax.imshow(img, cmap=cmap)
divider = makeaxeslocatable(ax) cax = divider.append_axes("right", size="10%", pad=0.05)
cb = fig.colorbar(im, cax=cax, orientation="vertical", label=cmap.name) cb.set_ticks([])
.. image:: images/colorbar.png :align: center
Advanced
generateoptimalcmap ^^^^^^^^^^^^^^^^^^^^^
You can extract the optimal number of colors from the image using the generateoptimalcmap method. Under the hood this performs the elbow method to determine the optimal number of clusters based on the sum of the squared distances between each pixel and it's cluster center.
.. code-block:: python3
cmaps, bestncolors, ssd = converter.generateoptimalcmap(maxcolors=10, randomstate=42)
bestcmap = cmaps[bestn_colors]
remove_transparent ^^^^^^^^^^^^^^^^^^^
In an image of the Los Angeles Lakers logo, the background is transparent. These pixels contribute to noise when generating the colors. Running the remove_transparent method will remove transparent pixels. Here's a comparison of the colormaps generated by the same image, without and with transparency removed.
Make two ImageConverter objects:
.. code-block:: python3
from img2cmap import ImageConverter
image_url = "https://loodibee.com/wp-content/uploads/nba-los-angeles-lakers-logo.png"
# Create two ImageConverters, one with transparency removed and one without converterwithtransparent = ImageConverter(image_url) converterwithtransparent.remove_transparent()
converternotransparent = ImageConverter(image_url)
cmapwithtransparent = converterwithtransparent.generate_cmap( ncolors=3, palettename="withtransparent", randomstate=42 ) cmapnotransparent = converternotransparent.generate_cmap( ncolors=3, palettename="notransparent", randomstate=42 )
Plot both colormaps with the image:
.. code-block:: python3
import matplotlib.pyplot as plt from mpltoolkits.axesgrid1 import makeaxeslocatable
for cmap in [cmapwithtransparent, cmapnotransparent]: fig, ax = plt.subplots(figsize=(7, 5))
ax.axis("off") img = converternotransparent.image im = ax.imshow(img, cmap=cmap)
divider = makeaxeslocatable(ax) cax = divider.append_axes("right", size="10%", pad=0.05)
cb = fig.colorbar(im, cax=cax, orientation="vertical", label=cmap.name) cb.set_ticks([])
.. image:: images/lakerswithtransparent.png :align: center
.. image:: images/lakersnotransparent.png :align: center
Notice, only after removing the transparent pixels, does the classic purple and gold show in the colormap.
resize ^^^^^^
There is a method of the ImageConverter class to resize images. It will preserve the aspect ratio, but reduce the size of the image.
.. code-block:: python3
def test_resize(): imageconverter = ImageConverter("tests/images/southbeachsunset.jpg") imageconverter.resize(size=(512, 512)) # preserves aspect ratio assert imageconverter.image.size == (512, 361)
hexcodes ^^^^^^^^
When running the generatecmap or the generateoptimal_cmap` methods the ImageConverter object will automatically capture the resulting hexcodes from the colormap and store them as an attribute.
.. code-block:: python3
from img2cmap import ImageConverter
image_url = "https://static1.bigstockphoto.com/3/2/3/large1500/323952496.jpg"
converter = ImageConverter(image_url) converter.generatecmap(ncolors=4, palettename="withtransparent", random_state=42) print(converter.hexcodes)
Output:
::
['#ba7469', '#dfd67d', '#5d536a', '#321e28']
Installation ============
::
pip install img2cmap
You can also install the in-development version with::
pip install https://github.com/arvkevi/img2cmap/archive/main.zip
Documentation =============
https://img2cmap.readthedocs.io/
Web App =======
Check out the web app at https://img2cmap.fly.dev
.. image:: images/webapp_image.png :align: center
Status ======
.. start-badges
.. list-table:: :stub-columns: 1
* - docs - |docs| * - tests - | |github-actions| | |codecov| * - package - | |version| |wheel| |supported-versions| |supported-implementations| .. |docs| image:: https://readthedocs.org/projects/img2cmap/badge/?style=flat :target: https://img2cmap.readthedocs.io/ :alt: Documentation Status
.. |github-actions| image:: https://github.com/arvkevi/img2cmap/actions/workflows/github-actions.yml/badge.svg :alt: GitHub Actions Build Status :target: https://github.com/arvkevi/img2cmap/actions
.. |codecov| image:: https://codecov.io/gh/arvkevi/img2cmap/branch/main/graphs/badge.svg?branch=main :alt: Coverage Status :target: https://codecov.io/github/arvkevi/img2cmap
.. |version| image:: https://img.shields.io/pypi/v/img2cmap.svg :alt: PyPI Package latest release :target: https://pypi.org/project/img2cmap
.. |wheel| image:: https://img.shields.io/pypi/wheel/img2cmap.svg :alt: PyPI Wheel :target: https://pypi.org/project/img2cmap
.. |supported-versions| image:: https://img.shields.io/pypi/pyversions/img2cmap.svg :alt: Supported versions :target: https://pypi.org/project/img2cmap
.. |supported-implementations| image:: https://img.shields.io/pypi/implementation/img2cmap.svg :alt: Supported implementations :target: https://pypi.org/project/img2cmap
.. end-badges
Development ===========
Install the development requirements:
::
pip install img2cmap[dev]
To run all the tests run::
tox
Note, to combine the coverage data from all the tox environments run:
.. list-table:: :widths: 10 90 :stub-columns: 1
- - Windows - ::
set PYTEST_ADDOPTS=--cov-append tox
- - Other - ::
PYTEST_ADDOPTS=--cov-append tox