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)
[t-SNE] Computing 91 nearest neighbors...
[t-SNE] Indexed 1797 samples in 0.000s...
[t-SNE] Computed neighbors for 1797 samples in 0.193s...
[t-SNE] Computed conditional probabilities for sample 1000 / 1797
[t-SNE] Computed conditional probabilities for sample 1797 / 1797
[t-SNE] Mean sigma: 157.044611
[t-SNE] Computed conditional probabilities in 0.114s
[t-SNE] Iteration 50: error = 75.1201019, gradient norm = 0.1297253 (50 iterations in 0.723s)
[t-SNE] Iteration 100: error = 64.9319153, gradient norm = 0.0576852 (50 iterations in 0.506s)
[t-SNE] Iteration 150: error = 62.8192482, gradient norm = 0.0384119 (50 iterations in 0.450s)
[t-SNE] Iteration 200: error = 62.1540604, gradient norm = 0.0200131 (50 iterations in 0.441s)
[t-SNE] Iteration 250: error = 61.8536758, gradient norm = 0.0230467 (50 iterations in 0.429s)
[t-SNE] KL divergence after 250 iterations with early exaggeration: 61.853676
[t-SNE] Iteration 300: error = 1.0489423, gradient norm = 0.0008685 (50 iterations in 0.414s)
[t-SNE] Iteration 350: error = 0.8758767, gradient norm = 0.0003661 (50 iterations in 0.414s)
[t-SNE] Iteration 400: error = 0.8189348, gradient norm = 0.0002448 (50 iterations in 0.413s)
[t-SNE] Iteration 450: error = 0.7939684, gradient norm = 0.0001800 (50 iterations in 0.420s)
[t-SNE] Iteration 500: error = 0.7798867, gradient norm = 0.0001526 (50 iterations in 0.418s)
[t-SNE] Iteration 550: error = 0.7710141, gradient norm = 0.0001333 (50 iterations in 0.413s)
[t-SNE] Iteration 600: error = 0.7652235, gradient norm = 0.0001147 (50 iterations in 0.416s)
[t-SNE] Iteration 650: error = 0.7608809, gradient norm = 0.0001077 (50 iterations in 0.415s)
[t-SNE] Iteration 700: error = 0.7574236, gradient norm = 0.0000968 (50 iterations in 0.409s)
[t-SNE] Iteration 750: error = 0.7545076, gradient norm = 0.0001011 (50 iterations in 0.406s)
[t-SNE] Iteration 800: error = 0.7525185, gradient norm = 0.0000963 (50 iterations in 0.405s)
[t-SNE] Iteration 850: error = 0.7507994, gradient norm = 0.0000894 (50 iterations in 0.406s)
[t-SNE] Iteration 900: error = 0.7493912, gradient norm = 0.0000859 (50 iterations in 0.408s)
[t-SNE] Iteration 950: error = 0.7478539, gradient norm = 0.0000864 (50 iterations in 0.411s)
[t-SNE] Iteration 1000: error = 0.7462668, gradient norm = 0.0000838 (50 iterations in 0.407s)
[t-SNE] KL divergence after 1000 iterations: 0.746267
..Scaling with: MinMaxScaler()
Mapping on data shaped (1797, 2) using lens shaped (1797, 2)
Minimal points in hypercube before clustering: 15
Creating 1225 hypercubes.
> Found 1 clusters in hypercube 0.
> Found 1 clusters in hypercube 1.
Cube_2 is empty.
Cube_3 is empty.
> Found 1 clusters in hypercube 4.
Cube_5 is empty.
Cube_6 is empty.
Cube_7 is empty.
Cube_8 is empty.
Cube_9 is empty.
Cube_10 is empty.
Cube_11 is empty.
Cube_12 is empty.
> Found 1 clusters in hypercube 13.
> Found 1 clusters in hypercube 14.
Cube_15 is empty.
Cube_16 is empty.
> Found 1 clusters in hypercube 17.
> Found 1 clusters in hypercube 18.
> Found 1 clusters in hypercube 19.
Cube_20 is empty.
Cube_21 is empty.
Cube_22 is empty.
Cube_23 is empty.
Cube_24 is empty.
Cube_25 is empty.
Cube_26 is empty.
Cube_27 is empty.
> Found 1 clusters in hypercube 28.
> Found 1 clusters in hypercube 29.
> Found 1 clusters in hypercube 30.
> Found 1 clusters in hypercube 31.
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.
> Found 1 clusters in hypercube 43.
Cube_44 is empty.
Cube_45 is empty.
Cube_46 is empty.
> Found 1 clusters in hypercube 47.
> Found 1 clusters in hypercube 48.
> Found 1 clusters in hypercube 49.
Cube_50 is empty.
Cube_51 is empty.
Cube_52 is empty.
Cube_53 is empty.
> Found 1 clusters in hypercube 54.
> Found 1 clusters in hypercube 55.
> Found 1 clusters in hypercube 56.
Cube_57 is empty.
Cube_58 is empty.
Cube_59 is empty.
> Found 1 clusters in hypercube 60.
> Found 1 clusters in hypercube 61.
> Found 1 clusters in hypercube 62.
> Found 1 clusters in hypercube 63.
Cube_64 is empty.
Cube_65 is empty.
Cube_66 is empty.
Cube_67 is empty.
Cube_68 is empty.
> Found 1 clusters in hypercube 69.
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.
> Found 1 clusters in hypercube 77.
> Found 1 clusters in hypercube 78.
Cube_79 is empty.
Cube_80 is empty.
> Found 1 clusters in hypercube 81.
> Found 1 clusters in hypercube 82.
Cube_83 is empty.
Cube_84 is empty.
Cube_85 is empty.
Cube_86 is empty.
Cube_87 is empty.
Cube_88 is empty.
Cube_89 is empty.
> Found 1 clusters in hypercube 90.
> Found 1 clusters in hypercube 91.
Cube_92 is empty.
Cube_93 is empty.
> Found 1 clusters in hypercube 94.
Cube_95 is empty.
Cube_96 is empty.
Cube_97 is empty.
> Found 1 clusters in hypercube 98.
Cube_99 is empty.
Cube_100 is empty.
Cube_101 is empty.
Cube_102 is empty.
Cube_103 is empty.
Cube_104 is empty.
Cube_105 is empty.
> Found 1 clusters in hypercube 106.
> Found 1 clusters in hypercube 107.
> Found 1 clusters in hypercube 108.
> Found 1 clusters in hypercube 109.
> Found 1 clusters in hypercube 110.
Cube_111 is empty.
Cube_112 is empty.
Cube_113 is empty.
Cube_114 is empty.
Cube_115 is empty.
> Found 1 clusters in hypercube 116.
> Found 1 clusters in hypercube 117.
> Found 1 clusters in hypercube 118.
> Found 1 clusters in hypercube 119.
> Found 1 clusters in hypercube 120.
Cube_121 is empty.
Cube_122 is empty.
Cube_123 is empty.
> Found 1 clusters in hypercube 124.
> Found 1 clusters in hypercube 125.
> Found 1 clusters in hypercube 126.
Cube_127 is empty.
Cube_128 is empty.
Cube_129 is empty.
Cube_130 is empty.
Cube_131 is empty.
Cube_132 is empty.
Cube_133 is empty.
Cube_134 is empty.
> Found 1 clusters in hypercube 135.
> Found 1 clusters in hypercube 136.
> Found 1 clusters in hypercube 137.
Cube_138 is empty.
Cube_139 is empty.
Cube_140 is empty.
Cube_141 is empty.
Cube_142 is empty.
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.
> Found 1 clusters in hypercube 149.
> Found 1 clusters in hypercube 150.
Cube_151 is empty.
Cube_152 is empty.
Cube_153 is empty.
Cube_154 is empty.
Cube_155 is empty.
Cube_156 is empty.
Cube_157 is empty.
Cube_158 is empty.
> Found 1 clusters in hypercube 159.
> Found 1 clusters in hypercube 160.
> Found 1 clusters in hypercube 161.
Cube_162 is empty.
Cube_163 is empty.
Cube_164 is empty.
Cube_165 is empty.
Cube_166 is empty.
> Found 1 clusters in hypercube 167.
Cube_168 is empty.
> Found 1 clusters in hypercube 169.
> Found 1 clusters in hypercube 170.
Cube_171 is empty.
> Found 1 clusters in hypercube 172.
> Found 1 clusters in hypercube 173.
> Found 1 clusters in hypercube 174.
> Found 1 clusters in hypercube 175.
Cube_176 is empty.
Cube_177 is empty.
Cube_178 is empty.
Cube_179 is empty.
Cube_180 is empty.
Cube_181 is empty.
Cube_182 is empty.
Cube_183 is empty.
Cube_184 is empty.
Cube_185 is empty.
Cube_186 is empty.
Cube_187 is empty.
Cube_188 is empty.
Cube_189 is empty.
> Found 1 clusters in hypercube 190.
> Found 1 clusters in hypercube 191.
Cube_192 is empty.
Cube_193 is empty.
Cube_194 is empty.
Cube_195 is empty.
Cube_196 is empty.
Cube_197 is empty.
Cube_198 is empty.
Cube_199 is empty.
Cube_200 is empty.
> Found 1 clusters in hypercube 201.
Cube_202 is empty.
Cube_203 is empty.
> Found 1 clusters in hypercube 204.
Cube_205 is empty.
Cube_206 is empty.
Cube_207 is empty.
Cube_208 is empty.
Cube_209 is empty.
Cube_210 is empty.
Cube_211 is empty.
> Found 1 clusters in hypercube 212.
Cube_213 is empty.
Cube_214 is empty.
Cube_215 is empty.
Cube_216 is empty.
Cube_217 is empty.
Cube_218 is empty.
Cube_219 is empty.
> Found 1 clusters in hypercube 220.
> Found 1 clusters in hypercube 221.
> Found 1 clusters in hypercube 222.
> Found 1 clusters in hypercube 223.
Cube_224 is empty.
Cube_225 is empty.
> Found 1 clusters in hypercube 226.
> Found 1 clusters in hypercube 227.
Cube_228 is empty.
Cube_229 is empty.
Cube_230 is empty.
Cube_231 is empty.
Cube_232 is empty.
Cube_233 is empty.
Cube_234 is empty.
Cube_235 is empty.
Cube_236 is empty.
Cube_237 is empty.
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.
Cube_244 is empty.
Cube_245 is empty.
> Found 1 clusters in hypercube 246.
Cube_247 is empty.
Cube_248 is empty.
Cube_249 is empty.
> Found 1 clusters in hypercube 250.
> Found 1 clusters in hypercube 251.
Cube_252 is empty.
Cube_253 is empty.
Cube_254 is empty.
Cube_255 is empty.
Cube_256 is empty.
Cube_257 is empty.
Cube_258 is empty.
> Found 1 clusters in hypercube 259.
Cube_260 is empty.
Cube_261 is empty.
> Found 1 clusters in hypercube 262.
Cube_263 is empty.
Cube_264 is empty.
> Found 1 clusters in hypercube 265.
> Found 1 clusters in hypercube 266.
> Found 1 clusters in hypercube 267.
Cube_268 is empty.
Cube_269 is empty.
Cube_270 is empty.
Cube_271 is empty.
Cube_272 is empty.
> Found 1 clusters in hypercube 273.
> Found 1 clusters in hypercube 274.
Cube_275 is empty.
Cube_276 is empty.
> Found 1 clusters in hypercube 277.
> Found 1 clusters in hypercube 278.
Cube_279 is empty.
Cube_280 is empty.
> Found 1 clusters in hypercube 281.
> Found 1 clusters in hypercube 282.
Cube_283 is empty.
> Found 1 clusters in hypercube 284.
> Found 1 clusters in hypercube 285.
Cube_286 is empty.
> Found 1 clusters in hypercube 287.
> Found 1 clusters in hypercube 288.
> Found 1 clusters in hypercube 289.
> Found 1 clusters in hypercube 290.
Cube_291 is empty.
Cube_292 is empty.
Cube_293 is empty.
Cube_294 is empty.
Cube_295 is empty.
> Found 1 clusters in hypercube 296.
Cube_297 is empty.
Cube_298 is empty.
> Found 1 clusters in hypercube 299.
> Found 1 clusters in hypercube 300.
Cube_301 is empty.
Cube_302 is empty.
Cube_303 is empty.
Cube_304 is empty.
> Found 1 clusters in hypercube 305.
Cube_306 is empty.
Cube_307 is empty.
Cube_308 is empty.
> Found 1 clusters in hypercube 309.
> Found 1 clusters in hypercube 310.
> Found 1 clusters in hypercube 311.
> Found 1 clusters in hypercube 312.
Cube_313 is empty.
Cube_314 is empty.
Cube_315 is empty.
Cube_316 is empty.
Cube_317 is empty.
Cube_318 is empty.
Cube_319 is empty.
Cube_320 is empty.
Cube_321 is empty.
Cube_322 is empty.
Cube_323 is empty.
Cube_324 is empty.
Cube_325 is empty.
Cube_326 is empty.
> Found 1 clusters in hypercube 327.
Cube_328 is empty.
Cube_329 is empty.
Cube_330 is empty.
Cube_331 is empty.
> Found 1 clusters in hypercube 332.
> Found 1 clusters in hypercube 333.
Cube_334 is empty.
Cube_335 is empty.
Cube_336 is empty.
Cube_337 is empty.
Cube_338 is empty.
Cube_339 is empty.
Cube_340 is empty.
Cube_341 is empty.
Cube_342 is empty.
Cube_343 is empty.
Cube_344 is empty.
Cube_345 is empty.
Cube_346 is empty.
Cube_347 is empty.
Cube_348 is empty.
Cube_349 is empty.
Cube_350 is empty.
Cube_351 is empty.
> Found 1 clusters in hypercube 352.
Cube_353 is empty.
Cube_354 is empty.
Cube_355 is empty.
Cube_356 is empty.
Cube_357 is empty.
Cube_358 is empty.
> Found 1 clusters in hypercube 359.
> Found 1 clusters in hypercube 360.
> Found 1 clusters in hypercube 361.
Cube_362 is empty.
Cube_363 is empty.
Cube_364 is empty.
Cube_365 is empty.
> Found 1 clusters in hypercube 366.
Cube_367 is empty.
Cube_368 is empty.
Cube_369 is empty.
> Found 1 clusters in hypercube 370.
> Found 1 clusters in hypercube 371.
> Found 1 clusters in hypercube 372.
Cube_373 is empty.
Cube_374 is empty.
Cube_375 is empty.
> Found 1 clusters in hypercube 376.
> Found 1 clusters in hypercube 377.
> Found 1 clusters in hypercube 378.
Cube_379 is empty.
Cube_380 is empty.
> Found 1 clusters in hypercube 381.
> Found 1 clusters in hypercube 382.
> Found 1 clusters in hypercube 383.
Cube_384 is empty.
Cube_385 is empty.
Cube_386 is empty.
Cube_387 is empty.
Cube_388 is empty.
Cube_389 is empty.
Cube_390 is empty.
Cube_391 is empty.
> Found 1 clusters in hypercube 392.
> Found 1 clusters in hypercube 393.
> Found 1 clusters in hypercube 394.
Cube_395 is empty.
Cube_396 is empty.
Cube_397 is empty.
Cube_398 is empty.
Cube_399 is empty.
Cube_400 is empty.
Cube_401 is empty.
Cube_402 is empty.
Cube_403 is empty.
> Found 1 clusters in hypercube 404.
> Found 1 clusters in hypercube 405.
Cube_406 is empty.
Cube_407 is empty.
Cube_408 is empty.
Cube_409 is empty.
> Found 1 clusters in hypercube 410.
> Found 1 clusters in hypercube 411.
> Found 1 clusters in hypercube 412.
> Found 1 clusters in hypercube 413.
Cube_414 is empty.
Cube_415 is empty.
Cube_416 is empty.
> Found 1 clusters in hypercube 417.
> Found 1 clusters in hypercube 418.
> Found 1 clusters in hypercube 419.
> Found 1 clusters in hypercube 420.
> Found 1 clusters in hypercube 421.
Cube_422 is empty.
Cube_423 is empty.
Cube_424 is empty.
Cube_425 is empty.
> Found 1 clusters in hypercube 426.
> Found 1 clusters in hypercube 427.
> Found 1 clusters in hypercube 428.
> Found 1 clusters in hypercube 429.
Cube_430 is empty.
Cube_431 is empty.
Cube_432 is empty.
> Found 1 clusters in hypercube 433.
> Found 1 clusters in hypercube 434.
> Found 1 clusters in hypercube 435.
Cube_436 is empty.
Cube_437 is empty.
> Found 1 clusters in hypercube 438.
Cube_439 is empty.
Cube_440 is empty.
> Found 1 clusters in hypercube 441.
> Found 1 clusters in hypercube 442.
Cube_443 is empty.
Cube_444 is empty.
Cube_445 is empty.
Cube_446 is empty.
Cube_447 is empty.
Cube_448 is empty.
Cube_449 is empty.
> Found 1 clusters in hypercube 450.
> Found 1 clusters in hypercube 451.
> Found 1 clusters in hypercube 452.
Cube_453 is empty.
Cube_454 is empty.
Cube_455 is empty.
Cube_456 is empty.
Cube_457 is empty.
Cube_458 is empty.
Cube_459 is empty.
Cube_460 is empty.
Cube_461 is empty.
Cube_462 is empty.
> Found 1 clusters in hypercube 463.
> Found 1 clusters in hypercube 464.
Cube_465 is empty.
Created 327 edges and 154 nodes in 0:00:00.182751.
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 10.266 seconds)