Note

Click here to download the full example code

# Digits DatasetΒΆ

This digits example shows two ways of customizing the tooltips options in the HTML visualization. It generates the visualization with tooltips set as the y-label, or number of the image. The second generated result uses the actual image in the tooltips.

Visualization with y-label tooltip

Visualization with custom tooltips

Out:

```
KeplerMapper(verbose=2)
..Composing projection pipeline of length 1:
Projections: TSNE()
Distance matrices: False
Scalers: MinMaxScaler()
..Projecting on data shaped (1797, 64)
..Projecting data using:
TSNE(verbose=2)
/home/docs/checkouts/readthedocs.org/user_builds/kepler-mapper/envs/latest/lib/python3.7/site-packages/sklearn/manifold/_t_sne.py:783: FutureWarning: The default initialization in TSNE will change from 'random' to 'pca' in 1.2.
FutureWarning,
/home/docs/checkouts/readthedocs.org/user_builds/kepler-mapper/envs/latest/lib/python3.7/site-packages/sklearn/manifold/_t_sne.py:793: FutureWarning: The default learning rate in TSNE will change from 200.0 to 'auto' in 1.2.
FutureWarning,
[t-SNE] Computing 91 nearest neighbors...
[t-SNE] Indexed 1797 samples in 0.000s...
[t-SNE] Computed neighbors for 1797 samples in 0.146s...
[t-SNE] Computed conditional probabilities for sample 1000 / 1797
[t-SNE] Computed conditional probabilities for sample 1797 / 1797
[t-SNE] Mean sigma: 186.389054
[t-SNE] Computed conditional probabilities in 0.093s
[t-SNE] Iteration 50: error = 73.2259140, gradient norm = 0.1355067 (50 iterations in 0.662s)
[t-SNE] Iteration 100: error = 63.6940079, gradient norm = 0.0416919 (50 iterations in 0.421s)
[t-SNE] Iteration 150: error = 62.2763786, gradient norm = 0.0354323 (50 iterations in 0.401s)
[t-SNE] Iteration 200: error = 61.7589874, gradient norm = 0.0270777 (50 iterations in 0.400s)
[t-SNE] Iteration 250: error = 61.5084076, gradient norm = 0.0206424 (50 iterations in 0.403s)
[t-SNE] KL divergence after 250 iterations with early exaggeration: 61.508408
[t-SNE] Iteration 300: error = 1.0322361, gradient norm = 0.0008276 (50 iterations in 0.385s)
[t-SNE] Iteration 350: error = 0.8631815, gradient norm = 0.0003459 (50 iterations in 0.381s)
[t-SNE] Iteration 400: error = 0.8109869, gradient norm = 0.0002200 (50 iterations in 0.378s)
[t-SNE] Iteration 450: error = 0.7886230, gradient norm = 0.0001825 (50 iterations in 0.380s)
[t-SNE] Iteration 500: error = 0.7765503, gradient norm = 0.0001475 (50 iterations in 0.383s)
[t-SNE] Iteration 550: error = 0.7690406, gradient norm = 0.0001310 (50 iterations in 0.385s)
[t-SNE] Iteration 600: error = 0.7636313, gradient norm = 0.0001221 (50 iterations in 0.393s)
[t-SNE] Iteration 650: error = 0.7598074, gradient norm = 0.0001119 (50 iterations in 0.385s)
[t-SNE] Iteration 700: error = 0.7562550, gradient norm = 0.0001030 (50 iterations in 0.384s)
[t-SNE] Iteration 750: error = 0.7535055, gradient norm = 0.0001019 (50 iterations in 0.384s)
[t-SNE] Iteration 800: error = 0.7507401, gradient norm = 0.0001092 (50 iterations in 0.383s)
[t-SNE] Iteration 850: error = 0.7488551, gradient norm = 0.0001020 (50 iterations in 0.380s)
[t-SNE] Iteration 900: error = 0.7475256, gradient norm = 0.0000897 (50 iterations in 0.379s)
[t-SNE] Iteration 950: error = 0.7461994, gradient norm = 0.0000985 (50 iterations in 0.375s)
[t-SNE] Iteration 1000: error = 0.7451306, gradient norm = 0.0000874 (50 iterations in 0.374s)
[t-SNE] KL divergence after 1000 iterations: 0.745131
..Scaling with: MinMaxScaler()
Mapping on data shaped (1797, 2) using lens shaped (1797, 2)
Minimal points in hypercube before clustering: 15
Creating 1225 hypercubes.
Cube_0 is empty.
Cube_1 is empty.
> Found 1 clusters in hypercube 2.
> Found 1 clusters in hypercube 3.
Cube_4 is empty.
Cube_5 is empty.
> Found 1 clusters in hypercube 6.
> Found 1 clusters in hypercube 7.
> Found 1 clusters in hypercube 8.
Cube_9 is empty.
Cube_10 is empty.
Cube_11 is empty.
> Found 1 clusters in hypercube 12.
> Found 1 clusters in hypercube 13.
> Found 1 clusters in hypercube 14.
> Found 1 clusters in hypercube 15.
> Found 1 clusters in hypercube 16.
Cube_17 is empty.
Cube_18 is empty.
> Found 1 clusters in hypercube 19.
> Found 1 clusters in hypercube 20.
> Found 1 clusters in hypercube 21.
> Found 1 clusters in hypercube 22.
Cube_23 is empty.
Cube_24 is empty.
Cube_25 is empty.
Cube_26 is empty.
Cube_27 is empty.
Cube_28 is empty.
> Found 1 clusters in hypercube 29.
> Found 1 clusters in hypercube 30.
Cube_31 is empty.
Cube_32 is empty.
Cube_33 is empty.
> Found 1 clusters in hypercube 34.
> Found 1 clusters in hypercube 35.
Cube_36 is empty.
Cube_37 is empty.
Cube_38 is empty.
Cube_39 is empty.
> Found 1 clusters in hypercube 40.
> Found 1 clusters in hypercube 41.
> Found 1 clusters in hypercube 42.
Cube_43 is empty.
> Found 1 clusters in hypercube 44.
> Found 1 clusters in hypercube 45.
Cube_46 is empty.
Cube_47 is empty.
> Found 1 clusters in hypercube 48.
> Found 1 clusters in hypercube 49.
> Found 1 clusters in hypercube 50.
> Found 1 clusters in hypercube 51.
Cube_52 is empty.
Cube_53 is empty.
> Found 1 clusters in hypercube 54.
Cube_55 is empty.
Cube_56 is empty.
Cube_57 is empty.
Cube_58 is empty.
> Found 1 clusters in hypercube 59.
> Found 1 clusters in hypercube 60.
> Found 1 clusters in hypercube 61.
Cube_62 is empty.
> Found 1 clusters in hypercube 63.
> Found 1 clusters in hypercube 64.
> Found 1 clusters in hypercube 65.
> Found 1 clusters in hypercube 66.
Cube_67 is empty.
Cube_68 is empty.
Cube_69 is empty.
Cube_70 is empty.
Cube_71 is empty.
Cube_72 is empty.
Cube_73 is empty.
Cube_74 is empty.
Cube_75 is empty.
Cube_76 is empty.
Cube_77 is empty.
Cube_78 is empty.
Cube_79 is empty.
Cube_80 is empty.
> Found 1 clusters in hypercube 81.
> Found 1 clusters in hypercube 82.
> Found 1 clusters in hypercube 83.
Cube_84 is empty.
Cube_85 is empty.
Cube_86 is empty.
Cube_87 is empty.
Cube_88 is empty.
> Found 1 clusters in hypercube 89.
> Found 1 clusters in hypercube 90.
Cube_91 is empty.
Cube_92 is empty.
Cube_93 is empty.
Cube_94 is empty.
> Found 1 clusters in hypercube 95.
> Found 1 clusters in hypercube 96.
Cube_97 is empty.
Cube_98 is empty.
> Found 1 clusters in hypercube 99.
> Found 1 clusters in hypercube 100.
> Found 1 clusters in hypercube 101.
> Found 1 clusters in hypercube 102.
Cube_103 is empty.
Cube_104 is empty.
> Found 1 clusters in hypercube 105.
Cube_106 is empty.
Cube_107 is empty.
> Found 1 clusters in hypercube 108.
> Found 1 clusters in hypercube 109.
> Found 1 clusters in hypercube 110.
Cube_111 is empty.
> Found 1 clusters in hypercube 112.
Cube_113 is empty.
> Found 1 clusters in hypercube 114.
> Found 1 clusters in hypercube 115.
> Found 1 clusters in hypercube 116.
> Found 1 clusters in hypercube 117.
Cube_118 is empty.
Cube_119 is empty.
> Found 1 clusters in hypercube 120.
> Found 1 clusters in hypercube 121.
Cube_122 is empty.
Cube_123 is empty.
> Found 1 clusters in hypercube 124.
Cube_125 is empty.
Cube_126 is empty.
Cube_127 is empty.
Cube_128 is empty.
> Found 1 clusters in hypercube 129.
> Found 1 clusters in hypercube 130.
> Found 1 clusters in hypercube 131.
> Found 1 clusters in hypercube 132.
> Found 1 clusters in hypercube 133.
Cube_134 is empty.
Cube_135 is empty.
Cube_136 is empty.
> Found 1 clusters in hypercube 137.
> Found 1 clusters in hypercube 138.
> Found 1 clusters in hypercube 139.
> Found 1 clusters in hypercube 140.
Cube_141 is empty.
> Found 1 clusters in hypercube 142.
Cube_143 is empty.
Cube_144 is empty.
> Found 1 clusters in hypercube 145.
Cube_146 is empty.
Cube_147 is empty.
Cube_148 is empty.
Cube_149 is empty.
Cube_150 is empty.
> Found 1 clusters in hypercube 151.
> Found 1 clusters in hypercube 152.
> Found 1 clusters in hypercube 153.
Cube_154 is empty.
Cube_155 is empty.
> Found 1 clusters in hypercube 156.
> Found 1 clusters in hypercube 157.
> Found 1 clusters in hypercube 158.
Cube_159 is empty.
Cube_160 is empty.
> Found 1 clusters in hypercube 161.
> Found 1 clusters in hypercube 162.
Cube_163 is empty.
Cube_164 is empty.
> Found 1 clusters in hypercube 165.
Cube_166 is empty.
Cube_167 is empty.
Cube_168 is empty.
Cube_169 is empty.
> Found 1 clusters in hypercube 170.
> Found 1 clusters in hypercube 171.
Cube_172 is empty.
Cube_173 is empty.
Cube_174 is empty.
> Found 1 clusters in hypercube 175.
> Found 1 clusters in hypercube 176.
Cube_177 is empty.
Cube_178 is empty.
Cube_179 is empty.
Cube_180 is empty.
Cube_181 is empty.
> Found 1 clusters in hypercube 182.
> Found 1 clusters in hypercube 183.
Cube_184 is empty.
Cube_185 is empty.
Cube_186 is empty.
Cube_187 is empty.
Cube_188 is empty.
Cube_189 is empty.
Cube_190 is empty.
Cube_191 is empty.
Cube_192 is empty.
Cube_193 is empty.
> Found 1 clusters in hypercube 194.
Cube_195 is empty.
Cube_196 is empty.
Cube_197 is empty.
Cube_198 is empty.
Cube_199 is empty.
Cube_200 is empty.
Cube_201 is empty.
Cube_202 is empty.
Cube_203 is empty.
Cube_204 is empty.
Cube_205 is empty.
Cube_206 is empty.
Cube_207 is empty.
Cube_208 is empty.
Cube_209 is empty.
> Found 1 clusters in hypercube 210.
Cube_211 is empty.
Cube_212 is empty.
Cube_213 is empty.
Cube_214 is empty.
Cube_215 is empty.
Cube_216 is empty.
> Found 1 clusters in hypercube 217.
Cube_218 is empty.
Cube_219 is empty.
Cube_220 is empty.
Cube_221 is empty.
Cube_222 is empty.
Cube_223 is empty.
Cube_224 is empty.
Cube_225 is empty.
> Found 1 clusters in hypercube 226.
> Found 1 clusters in hypercube 227.
> Found 1 clusters in hypercube 228.
Cube_229 is empty.
Cube_230 is empty.
> Found 1 clusters in hypercube 231.
Cube_232 is empty.
> Found 1 clusters in hypercube 233.
> Found 1 clusters in hypercube 234.
> Found 1 clusters in hypercube 235.
> Found 1 clusters in hypercube 236.
> Found 1 clusters in hypercube 237.
Cube_238 is empty.
Cube_239 is empty.
> Found 1 clusters in hypercube 240.
> Found 1 clusters in hypercube 241.
> Found 1 clusters in hypercube 242.
Cube_243 is empty.
> Found 1 clusters in hypercube 244.
> Found 1 clusters in hypercube 245.
> Found 1 clusters in hypercube 246.
> Found 1 clusters in hypercube 247.
> Found 1 clusters in hypercube 248.
> Found 1 clusters in hypercube 249.
Cube_250 is empty.
> Found 1 clusters in hypercube 251.
> Found 1 clusters in hypercube 252.
> Found 1 clusters in hypercube 253.
> Found 1 clusters in hypercube 254.
Cube_255 is empty.
Cube_256 is empty.
> Found 1 clusters in hypercube 257.
> Found 1 clusters in hypercube 258.
> Found 1 clusters in hypercube 259.
Cube_260 is empty.
Cube_261 is empty.
> Found 1 clusters in hypercube 262.
> Found 1 clusters in hypercube 263.
> Found 1 clusters in hypercube 264.
> Found 1 clusters in hypercube 265.
Cube_266 is empty.
Cube_267 is empty.
Cube_268 is empty.
> Found 1 clusters in hypercube 269.
> Found 1 clusters in hypercube 270.
> Found 1 clusters in hypercube 271.
Cube_272 is empty.
Cube_273 is empty.
Cube_274 is empty.
Cube_275 is empty.
Cube_276 is empty.
Cube_277 is empty.
> Found 1 clusters in hypercube 278.
Cube_279 is empty.
Cube_280 is empty.
Cube_281 is empty.
Cube_282 is empty.
Cube_283 is empty.
Cube_284 is empty.
Cube_285 is empty.
Cube_286 is empty.
Cube_287 is empty.
Cube_288 is empty.
Cube_289 is empty.
Cube_290 is empty.
Cube_291 is empty.
Cube_292 is empty.
> Found 1 clusters in hypercube 293.
Cube_294 is empty.
Cube_295 is empty.
Cube_296 is empty.
Cube_297 is empty.
Cube_298 is empty.
Cube_299 is empty.
Cube_300 is empty.
Cube_301 is empty.
Cube_302 is empty.
Cube_303 is empty.
Cube_304 is empty.
Cube_305 is empty.
> Found 1 clusters in hypercube 306.
> Found 1 clusters in hypercube 307.
Cube_308 is empty.
Cube_309 is empty.
Cube_310 is empty.
Cube_311 is empty.
> Found 1 clusters in hypercube 312.
> Found 1 clusters in hypercube 313.
> Found 1 clusters in hypercube 314.
Cube_315 is empty.
Cube_316 is empty.
> Found 1 clusters in hypercube 317.
> Found 1 clusters in hypercube 318.
> Found 1 clusters in hypercube 319.
> Found 1 clusters in hypercube 320.
Cube_321 is empty.
Cube_322 is empty.
Cube_323 is empty.
Cube_324 is empty.
> Found 1 clusters in hypercube 325.
> Found 1 clusters in hypercube 326.
> Found 1 clusters in hypercube 327.
Cube_328 is empty.
Cube_329 is empty.
Cube_330 is empty.
> Found 1 clusters in hypercube 331.
> Found 1 clusters in hypercube 332.
Cube_333 is empty.
Cube_334 is empty.
Cube_335 is empty.
Cube_336 is empty.
Cube_337 is empty.
Cube_338 is empty.
Cube_339 is empty.
> Found 1 clusters in hypercube 340.
> Found 1 clusters in hypercube 341.
> Found 1 clusters in hypercube 342.
> Found 1 clusters in hypercube 343.
> Found 1 clusters in hypercube 344.
Cube_345 is empty.
Cube_346 is empty.
> Found 1 clusters in hypercube 347.
> Found 1 clusters in hypercube 348.
> Found 1 clusters in hypercube 349.
> Found 1 clusters in hypercube 350.
> Found 1 clusters in hypercube 351.
> Found 1 clusters in hypercube 352.
Cube_353 is empty.
Cube_354 is empty.
Cube_355 is empty.
> Found 1 clusters in hypercube 356.
> Found 1 clusters in hypercube 357.
Cube_358 is empty.
Cube_359 is empty.
Cube_360 is empty.
Cube_361 is empty.
Cube_362 is empty.
Cube_363 is empty.
Cube_364 is empty.
Cube_365 is empty.
Cube_366 is empty.
Cube_367 is empty.
Cube_368 is empty.
> Found 1 clusters in hypercube 369.
Cube_370 is empty.
Created 338 edges and 149 nodes in 0:00:00.175596.
Output graph examples to html
Wrote visualization to: output/digits_custom_tooltips.html
Wrote visualization to: output/digits_ylabel_tooltips.html
no display found. Using non-interactive Agg backend
```

```
import io
import sys
import base64
import matplotlib.pyplot as plt
import numpy as np
import sklearn
from sklearn import datasets
from sklearn.preprocessing import MinMaxScaler
import kmapper as km
try:
from PIL import Image
except ImportError as e:
print("This example requires Pillow. Run `pip install pillow` and then try again.")
sys.exit()
# Load digits data
data, labels = datasets.load_digits().data, datasets.load_digits().target
# Raw data is (0, 16), so scale to 8 bits (pillow can't handle 4-bit greyscale PNG depth)
scaler = MinMaxScaler(feature_range=(0, 255))
data = scaler.fit_transform(data).astype(np.uint8)
# Create images for a custom tooltip array
tooltip_s = []
for image_data in data:
with io.BytesIO() as output:
img = Image.fromarray(image_data.reshape((8, 8)), "L")
img.save(output, "PNG")
contents = output.getvalue()
img_encoded = base64.b64encode(contents)
img_tag = """<img src="data:image/png;base64,{}">""".format(
img_encoded.decode("utf-8")
)
tooltip_s.append(img_tag)
tooltip_s = np.array(
tooltip_s
) # need to make sure to feed it as a NumPy array, not a list
# Initialize to use t-SNE with 2 components (reduces data to 2 dimensions). Also note high overlap_percentage.
mapper = km.KeplerMapper(verbose=2)
# Fit and transform data
projected_data = mapper.fit_transform(data, projection=sklearn.manifold.TSNE())
# Create the graph (we cluster on the projected data and suffer projection loss)
graph = mapper.map(
projected_data,
clusterer=sklearn.cluster.DBSCAN(eps=0.3, min_samples=15),
cover=km.Cover(35, 0.4),
)
# Create the visualizations (increased the graph_gravity for a tighter graph-look.)
print("Output graph examples to html")
# Tooltips with image data for every cluster member
mapper.visualize(
graph,
title="Handwritten digits Mapper",
path_html="output/digits_custom_tooltips.html",
color_values=labels,
color_function_name="labels",
custom_tooltips=tooltip_s,
)
# Tooltips with the target y-labels for every cluster member
mapper.visualize(
graph,
title="Handwritten digits Mapper",
path_html="output/digits_ylabel_tooltips.html",
custom_tooltips=labels,
)
# Matplotlib examples
km.draw_matplotlib(graph, layout="spring")
plt.show()
```

**Total running time of the script:** ( 0 minutes 9.526 seconds)