10000 Merge pull request #17888 from bdice/colormap-repr · matplotlib/matplotlib@068e0f4 · GitHub
[go: up one dir, main page]

Skip to content

Commit 068e0f4

Browse files
authored
Merge pull request #17888 from bdice/colormap-repr
ENH: Add _repr_png_ and _repr_html_ to Colormap objects.
2 parents 156dfa4 + 9d46338 commit 068e0f4

File tree

3 files changed

+60
-0
lines changed

3 files changed

+60
-0
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
IPython representations for Colormap objects
2+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
3+
4+
The `matplotlib.colors.Colormap` object now has image representations for
5+
IPython / Jupyter backends. Cells returning a color map on the last line will
6+
display an image of the color map.

lib/matplotlib/colors.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,12 +65,17 @@
6565
.. _xkcd color survey: https://xkcd.com/color/rgb/
6666
"""
6767

68+
import base64
6869
from collections.abc import Sized
6970
import functools
71+
import io
7072
import itertools
7173
from numbers import Number
7274
import re
75+
from PIL import Image
76+
from PIL.PngImagePlugin import PngInfo
7377

78+
import matplotlib as mpl
7479
import numpy as np
7580
import matplotlib.cbook as cbook
7681
from matplotlib import docstring
@@ -691,6 +696,33 @@ def reversed(self, name=None):
691696
"""
692697
raise NotImplementedError()
693698

699+
def _repr_png_(self):
700+
"""Generate a PNG representation of the Colormap."""
701+
IMAGE_SIZE = (400, 50)
702+
X = np.tile(np.linspace(0, 1, IMAGE_SIZE[0]), (IMAGE_SIZE[1], 1))
703+
pixels = self(X, bytes=True)
704+
png_bytes = io.BytesIO()
705+
title = self.name + ' color map'
706+
author = f'Matplotlib v{mpl.__version__}, https://matplotlib.org'
707+
pnginfo = PngInfo()
708+
pnginfo.add_text('Title', title)
709+
pnginfo.add_text('Description', title)
710+
pnginfo.add_text('Author', author)
711+
pnginfo.add_text('Software', author)
712+
Image.fromarray(pixels).save(png_bytes, format='png', pnginfo=pnginfo)
713+
return png_bytes.getvalue()
714+
715+
def _repr_html_(self):
716+
"""Generate an HTML representation of the Colormap."""
717+
png_bytes = self._repr_png_()
718+
png_base64 = base64.b64encode(png_bytes).decode('ascii')
719+
return ('<strong>' + self.name + '</strong>' +
720+
'<img ' +
721+
'alt="' + self.name + ' color map" ' +
722+
'title="' + self.name + '"' +
723+
'style="border: 1px solid #555;" ' +
724+
'src="data:image/png;base64,' + png_base64 + '">')
725+
694726

695727
class LinearSegmentedColormap(Colormap):
696728
"""

lib/matplotlib/tests/test_colors.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import copy
22
import itertools
33

4+
from io import BytesIO
45
import numpy as np
6+
from PIL import Image
57
import pytest
68

79
from numpy.testing import assert_array_equal, assert_array_almost_equal
@@ -1140,3 +1142,23 @@ def test_hex_shorthand_notation():
11401142
def test_DivergingNorm_deprecated():
11411143
with pytest.warns(cbook.MatplotlibDeprecationWarning):
11421144
norm = mcolors.DivergingNorm(vcenter=0)
1145+
1146+
1147+
def test_repr_png():
1148+
cmap = plt.get_cmap('viridis')
1149+
png = cmap._repr_png_()
1150+
assert len(png) > 0
1151+
img = Image.open(BytesIO(png))
1152+
assert img.width > 0
1153+
assert img.height > 0
1154+
assert 'Title' in img.text
1155+
assert 'Description' in img.text
1156+
assert 'Author' in img.text
1157+
assert 'Software' in img.text
1158+
1159+
1160+
def test_repr_html():
1161+
cmap = plt.get_cmap('viridis')
1162+
html = cmap._repr_html_()
1163+
assert len(html) > 0
1164+
assert cmap.name in html

0 commit comments

Comments
 (0)
0