# 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

```
[1]:
```

```
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
from pathlib import Path
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
if Path("output/").is_dir():
prepend = "output/"
else:
prepend = "./"
mapper.visualize(
graph,
title="Handwritten digits Mapper",
path_html=prepend + "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=prepend + "digits_ylabel_tooltips.html",
custom_tooltips=labels,
)
# Matplotlib examples
km.draw_matplotlib(graph, layout="spring")
plt.show()
```

```
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.082s...
[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.070s
[t-SNE] Iteration 50: error = 67.4627762, gradient norm = 0.0413627 (50 iterations in 0.591s)
[t-SNE] Iteration 100: error = 62.6629944, gradient norm = 0.0064923 (50 iterations in 0.475s)
[t-SNE] Iteration 150: error = 61.8384399, gradient norm = 0.0029054 (50 iterations in 0.482s)
[t-SNE] Iteration 200: error = 61.5377045, gradient norm = 0.0015508 (50 iterations in 0.485s)
[t-SNE] Iteration 250: error = 61.3869705, gradient norm = 0.0013344 (50 iterations in 0.493s)
[t-SNE] KL divergence after 250 iterations with early exaggeration: 61.386971
[t-SNE] Iteration 300: error = 1.3390938, gradient norm = 0.0208437 (50 iterations in 0.462s)
[t-SNE] Iteration 350: error = 1.0355185, gradient norm = 0.0159531 (50 iterations in 0.446s)
[t-SNE] Iteration 400: error = 0.9212385, gradient norm = 0.0134439 (50 iterations in 0.440s)
[t-SNE] Iteration 450: error = 0.8610491, gradient norm = 0.0118203 (50 iterations in 0.441s)
[t-SNE] Iteration 500: error = 0.8252493, gradient norm = 0.0103926 (50 iterations in 0.442s)
[t-SNE] Iteration 550: error = 0.8026900, gradient norm = 0.0091607 (50 iterations in 0.444s)
[t-SNE] Iteration 600: error = 0.7873806, gradient norm = 0.0077083 (50 iterations in 0.443s)
[t-SNE] Iteration 650: error = 0.7775064, gradient norm = 0.0064036 (50 iterations in 0.437s)
[t-SNE] Iteration 700: error = 0.7710885, gradient norm = 0.0052207 (50 iterations in 0.441s)
[t-SNE] Iteration 750: error = 0.7663851, gradient norm = 0.0039145 (50 iterations in 0.443s)
[t-SNE] Iteration 800: error = 0.7635172, gradient norm = 0.0032798 (50 iterations in 0.449s)
[t-SNE] Iteration 850: error = 0.7610255, gradient norm = 0.0029787 (50 iterations in 0.445s)
[t-SNE] Iteration 900: error = 0.7589423, gradient norm = 0.0026550 (50 iterations in 0.446s)
[t-SNE] Iteration 950: error = 0.7572140, gradient norm = 0.0023271 (50 iterations in 0.447s)
[t-SNE] Iteration 1000: error = 0.7553420, gradient norm = 0.0024630 (50 iterations in 0.450s)
[t-SNE] KL divergence after 1000 iterations: 0.755342
..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.
> Found 1 clusters in hypercube 1.
Cube_2 is empty.
Cube_3 is empty.
Cube_4 is empty.
Cube_5 is empty.
> Found 1 clusters in hypercube 6.
Cube_7 is empty.
Cube_8 is empty.
> Found 1 clusters in hypercube 9.
> Found 1 clusters in hypercube 10.
Cube_11 is empty.
Cube_12 is empty.
Cube_13 is empty.
Cube_14 is empty.
Cube_15 is empty.
> Found 1 clusters in hypercube 16.
> 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.
> Found 1 clusters in hypercube 24.
> Found 1 clusters in hypercube 25.
> Found 1 clusters in hypercube 26.
> Found 1 clusters in hypercube 27.
> Found 1 clusters in hypercube 28.
Cube_29 is empty.
Cube_30 is empty.
> Found 1 clusters in hypercube 31.
Cube_32 is empty.
Cube_33 is empty.
Cube_34 is empty.
Cube_35 is empty.
Cube_36 is empty.
> Found 1 clusters in hypercube 37.
> Found 1 clusters in hypercube 38.
> Found 1 clusters in hypercube 39.
Cube_40 is empty.
Cube_41 is empty.
Cube_42 is empty.
Cube_43 is empty.
> Found 1 clusters in hypercube 44.
> Found 1 clusters in hypercube 45.
> Found 1 clusters in hypercube 46.
> Found 1 clusters in hypercube 47.
Cube_48 is empty.
Cube_49 is empty.
Cube_50 is empty.
Cube_51 is empty.
Cube_52 is empty.
Cube_53 is empty.
Cube_54 is empty.
Cube_55 is empty.
Cube_56 is empty.
Cube_57 is empty.
Cube_58 is empty.
Cube_59 is empty.
Cube_60 is empty.
> Found 1 clusters in hypercube 61.
> Found 1 clusters in hypercube 62.
> Found 1 clusters in hypercube 63.
> Found 1 clusters in hypercube 64.
Cube_65 is empty.
Cube_66 is empty.
> Found 1 clusters in hypercube 67.
> Found 1 clusters in hypercube 68.
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.
> Found 1 clusters in hypercube 80.
> Found 1 clusters in hypercube 81.
> Found 1 clusters in hypercube 82.
Cube_83 is empty.
Cube_84 is empty.
> Found 1 clusters in hypercube 85.
> Found 1 clusters in hypercube 86.
> Found 1 clusters in hypercube 87.
Cube_88 is empty.
Cube_89 is empty.
Cube_90 is empty.
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.
> Found 1 clusters in hypercube 97.
Cube_98 is empty.
Cube_99 is empty.
> 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.
Cube_105 is empty.
Cube_106 is empty.
Cube_107 is empty.
Cube_108 is empty.
Cube_109 is empty.
Cube_110 is empty.
Cube_111 is empty.
Cube_112 is empty.
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.
Cube_120 is empty.
Cube_121 is empty.
Cube_122 is empty.
Cube_123 is empty.
Cube_124 is empty.
Cube_125 is empty.
Cube_126 is empty.
Cube_127 is empty.
Cube_128 is empty.
Cube_129 is empty.
Cube_130 is empty.
Cube_131 is empty.
Cube_132 is empty.
> Found 1 clusters in hypercube 133.
> Found 1 clusters in hypercube 134.
Cube_135 is empty.
Cube_136 is empty.
Cube_137 is empty.
Cube_138 is empty.
Cube_139 is empty.
Cube_140 is empty.
> Found 1 clusters in hypercube 141.
> Found 1 clusters in hypercube 142.
> Found 1 clusters in hypercube 143.
> Found 1 clusters in hypercube 144.
Cube_145 is empty.
> Found 1 clusters in hypercube 146.
Cube_147 is empty.
Cube_148 is empty.
Cube_149 is empty.
Cube_150 is empty.
Cube_151 is empty.
Cube_152 is empty.
Cube_153 is empty.
Cube_154 is empty.
> Found 1 clusters in hypercube 155.
> Found 1 clusters in hypercube 156.
Cube_157 is empty.
Cube_158 is empty.
Cube_159 is empty.
Cube_160 is empty.
Cube_161 is empty.
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.
> Found 1 clusters in hypercube 168.
> Found 1 clusters in hypercube 169.
Cube_170 is empty.
Cube_171 is empty.
Cube_172 is empty.
Cube_173 is empty.
Cube_174 is empty.
Cube_175 is empty.
Cube_176 is empty.
> Found 1 clusters in hypercube 177.
> Found 1 clusters in hypercube 178.
Cube_179 is empty.
Cube_180 is empty.
Cube_181 is empty.
Cube_182 is empty.
Cube_183 is empty.
> Found 1 clusters in hypercube 184.
> Found 1 clusters in hypercube 185.
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.
> Found 1 clusters in hypercube 193.
> Found 1 clusters in hypercube 194.
> Found 1 clusters in hypercube 195.
Cube_196 is empty.
Cube_197 is empty.
> Found 1 clusters in hypercube 198.
> Found 1 clusters in hypercube 199.
> Found 1 clusters in hypercube 200.
Cube_201 is empty.
Cube_202 is empty.
Cube_203 is empty.
Cube_204 is empty.
Cube_205 is empty.
Cube_206 is empty.
> Found 1 clusters in hypercube 207.
Cube_208 is empty.
Cube_209 is empty.
Cube_210 is empty.
Cube_211 is empty.
Cube_212 is empty.
> Found 1 clusters in hypercube 213.
> Found 1 clusters in hypercube 214.
Cube_215 is empty.
> Found 1 clusters in hypercube 216.
> Found 1 clusters in hypercube 217.
> Found 1 clusters in hypercube 218.
> Found 1 clusters in hypercube 219.
Cube_220 is empty.
Cube_221 is empty.
> Found 1 clusters in hypercube 222.
> Found 1 clusters in hypercube 223.
> Found 1 clusters in hypercube 224.
Cube_225 is empty.
Cube_226 is empty.
Cube_227 is empty.
Cube_228 is empty.
Cube_229 is empty.
> Found 1 clusters in hypercube 230.
> Found 1 clusters in hypercube 231.
> Found 1 clusters in hypercube 232.
Cube_233 is empty.
Cube_234 is empty.
Cube_235 is empty.
Cube_236 is empty.
Cube_237 is empty.
> Found 1 clusters in hypercube 238.
> Found 1 clusters in hypercube 239.
> Found 1 clusters in hypercube 240.
> Found 1 clusters in hypercube 241.
> Found 1 clusters in hypercube 242.
> Found 1 clusters in hypercube 243.
> Found 1 clusters in hypercube 244.
Cube_245 is empty.
Cube_246 is empty.
Cube_247 is empty.
> Found 1 clusters in hypercube 248.
Cube_249 is empty.
Cube_250 is empty.
> Found 1 clusters in hypercube 251.
Cube_252 is empty.
Cube_253 is empty.
Cube_254 is empty.
> Found 1 clusters in hypercube 255.
> Found 1 clusters in hypercube 256.
> Found 1 clusters in hypercube 257.
Cube_258 is empty.
Cube_259 is empty.
Cube_260 is empty.
> Found 1 clusters in hypercube 261.
> Found 1 clusters in hypercube 262.
> Found 1 clusters in hypercube 263.
Cube_264 is empty.
> Found 1 clusters in hypercube 265.
> Found 1 clusters in hypercube 266.
> Found 1 clusters in hypercube 267.
> Found 1 clusters in hypercube 268.
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.
> Found 1 clusters in hypercube 275.
Cube_276 is empty.
Cube_277 is empty.
Cube_278 is empty.
Cube_279 is empty.
> Found 1 clusters in hypercube 280.
Cube_281 is empty.
Cube_282 is empty.
> Found 1 clusters in hypercube 283.
> Found 1 clusters in hypercube 284.
> Found 1 clusters in hypercube 285.
Cube_286 is empty.
Cube_287 is empty.
Cube_288 is empty.
> Found 1 clusters in hypercube 289.
> Found 1 clusters in hypercube 290.
Cube_291 is empty.
> Found 1 clusters in hypercube 292.
> Found 1 clusters in hypercube 293.
> Found 1 clusters in hypercube 294.
Cube_295 is empty.
Cube_296 is empty.
Cube_297 is empty.
Cube_298 is empty.
Cube_299 is empty.
> Found 1 clusters in hypercube 300.
> Found 1 clusters in hypercube 301.
> Found 1 clusters in hypercube 302.
Cube_303 is empty.
Cube_304 is empty.
Cube_305 is empty.
Cube_306 is empty.
Cube_307 is empty.
Cube_308 is empty.
Cube_309 is empty.
Cube_310 is empty.
Cube_311 is empty.
Cube_312 is empty.
Cube_313 is empty.
Cube_314 is empty.
Cube_315 is empty.
Cube_316 is empty.
Cube_317 is empty.
> Found 1 clusters in hypercube 318.
> Found 1 clusters in hypercube 319.
> Found 1 clusters in hypercube 320.
Cube_321 is empty.
> Found 1 clusters in hypercube 322.
> Found 1 clusters in hypercube 323.
Cube_324 is empty.
Cube_325 is empty.
Cube_326 is empty.
Cube_327 is empty.
Cube_328 is empty.
Cube_329 is empty.
Cube_330 is empty.
Cube_331 is empty.
Cube_332 is empty.
> Found 1 clusters in hypercube 333.
> Found 1 clusters in hypercube 334.
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.
> Found 1 clusters in hypercube 342.
Cube_343 is empty.
> Found 1 clusters in hypercube 344.
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.
Cube_352 is empty.
Cube_353 is empty.
Cube_354 is empty.
Cube_355 is empty.
Cube_356 is empty.
> Found 1 clusters in hypercube 357.
> Found 1 clusters in hypercube 358.
> Found 1 clusters in hypercube 359.
> Found 1 clusters in hypercube 360.
Cube_361 is empty.
Cube_362 is empty.
Cube_363 is empty.
> Found 1 clusters in hypercube 364.
> Found 1 clusters in hypercube 365.
> Found 1 clusters in hypercube 366.
Cube_367 is empty.
Cube_368 is empty.
> Found 1 clusters in hypercube 369.
Cube_370 is empty.
Cube_371 is empty.
> Found 1 clusters in hypercube 372.
> Found 1 clusters in hypercube 373.
> Found 1 clusters in hypercube 374.
> Found 1 clusters in hypercube 375.
Cube_376 is empty.
Cube_377 is empty.
> Found 1 clusters in hypercube 378.
Cube_379 is empty.
Cube_380 is empty.
Cube_381 is empty.
Cube_382 is empty.
> Found 1 clusters in hypercube 383.
> Found 1 clusters in hypercube 384.
> Found 1 clusters in hypercube 385.
> Found 1 clusters in hypercube 386.
Cube_387 is empty.
Cube_388 is empty.
Cube_389 is empty.
Cube_390 is empty.
Cube_391 is empty.
Cube_392 is empty.
Cube_393 is empty.
Cube_394 is empty.
> Found 1 clusters in hypercube 395.
> Found 1 clusters in hypercube 396.
> Found 1 clusters in hypercube 397.
Cube_398 is empty.
> Found 1 clusters in hypercube 399.
> Found 1 clusters in hypercube 400.
> Found 1 clusters in hypercube 401.
> Found 1 clusters in hypercube 402.
Cube_403 is empty.
Cube_404 is empty.
Cube_405 is empty.
Cube_406 is empty.
Cube_407 is empty.
Cube_408 is empty.
> Found 1 clusters in hypercube 409.
> Found 1 clusters in hypercube 410.
> Found 1 clusters in hypercube 411.
Cube_412 is empty.
Cube_413 is empty.
Cube_414 is empty.
Cube_415 is empty.
> Found 1 clusters in hypercube 416.
> Found 1 clusters in hypercube 417.
> Found 1 clusters in hypercube 418.
Cube_419 is empty.
Cube_420 is empty.
Cube_421 is empty.
> Found 1 clusters in hypercube 422.
> Found 1 clusters in hypercube 423.
Cube_424 is empty.
Created 342 edges and 153 nodes in 0:00:00.202593.
Output graph examples to html
Wrote visualization to: ./digits_custom_tooltips.html
Wrote visualization to: ./digits_ylabel_tooltips.html
no display found. Using non-interactive Agg backend
```