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.088s...
[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.060s
[t-SNE] Iteration 50: error = 67.4918900, gradient norm = 0.0397445 (50 iterations in 0.441s)
[t-SNE] Iteration 100: error = 62.6574287, gradient norm = 0.0072191 (50 iterations in 0.353s)
[t-SNE] Iteration 150: error = 61.8355827, gradient norm = 0.0033256 (50 iterations in 0.353s)
[t-SNE] Iteration 200: error = 61.5347366, gradient norm = 0.0020062 (50 iterations in 0.356s)
[t-SNE] Iteration 250: error = 61.3842926, gradient norm = 0.0012161 (50 iterations in 0.364s)
[t-SNE] KL divergence after 250 iterations with early exaggeration: 61.384293
[t-SNE] Iteration 300: error = 1.3391695, gradient norm = 0.0208109 (50 iterations in 0.349s)
[t-SNE] Iteration 350: error = 1.0354385, gradient norm = 0.0160268 (50 iterations in 0.339s)
[t-SNE] Iteration 400: error = 0.9205701, gradient norm = 0.0134286 (50 iterations in 0.335s)
[t-SNE] Iteration 450: error = 0.8606834, gradient norm = 0.0117502 (50 iterations in 0.341s)
[t-SNE] Iteration 500: error = 0.8249393, gradient norm = 0.0105694 (50 iterations in 0.339s)
[t-SNE] Iteration 550: error = 0.8022854, gradient norm = 0.0092166 (50 iterations in 0.336s)
[t-SNE] Iteration 600: error = 0.7872913, gradient norm = 0.0078643 (50 iterations in 0.337s)
[t-SNE] Iteration 650: error = 0.7771439, gradient norm = 0.0064516 (50 iterations in 0.331s)
[t-SNE] Iteration 700: error = 0.7707941, gradient norm = 0.0047570 (50 iterations in 0.332s)
[t-SNE] Iteration 750: error = 0.7666692, gradient norm = 0.0040806 (50 iterations in 0.336s)
[t-SNE] Iteration 800: error = 0.7634986, gradient norm = 0.0034643 (50 iterations in 0.340s)
[t-SNE] Iteration 850: error = 0.7604496, gradient norm = 0.0029006 (50 iterations in 0.336s)
[t-SNE] Iteration 900: error = 0.7583166, gradient norm = 0.0024575 (50 iterations in 0.336s)
[t-SNE] Iteration 950: error = 0.7563731, gradient norm = 0.0023835 (50 iterations in 0.338s)
[t-SNE] Iteration 1000: error = 0.7547204, gradient norm = 0.0022369 (50 iterations in 0.339s)
[t-SNE] KL divergence after 1000 iterations: 0.754720
..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.
Cube_4 is empty.
Cube_5 is empty.
Cube_6 is empty.
Cube_7 is empty.
> Found 1 clusters in hypercube 8.
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.
> Found 1 clusters in hypercube 15.
> Found 1 clusters in hypercube 16.
Cube_17 is empty.
Cube_18 is empty.
Cube_19 is empty.
Cube_20 is empty.
Cube_21 is empty.
Cube_22 is empty.
> Found 1 clusters in hypercube 23.
> Found 1 clusters in hypercube 24.
> Found 1 clusters in hypercube 25.
> Found 1 clusters in hypercube 26.
> Found 1 clusters in hypercube 27.
Cube_28 is empty.
Cube_29 is empty.
> Found 1 clusters in hypercube 30.
Cube_31 is empty.
Cube_32 is empty.
> Found 1 clusters in hypercube 33.
Cube_34 is empty.
Cube_35 is empty.
> Found 1 clusters in hypercube 36.
> Found 1 clusters in hypercube 37.
> Found 1 clusters in hypercube 38.
Cube_39 is empty.
Cube_40 is empty.
Cube_41 is empty.
Cube_42 is empty.
> Found 1 clusters in hypercube 43.
> Found 1 clusters in hypercube 44.
> Found 1 clusters in hypercube 45.
> Found 1 clusters in hypercube 46.
Cube_47 is empty.
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.
> Found 1 clusters in hypercube 57.
> Found 1 clusters in hypercube 58.
> Found 1 clusters in hypercube 59.
> Found 1 clusters in hypercube 60.
Cube_61 is empty.
Cube_62 is empty.
> Found 1 clusters in hypercube 63.
> Found 1 clusters in hypercube 64.
Cube_65 is empty.
Cube_66 is empty.
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.
> Found 1 clusters in hypercube 75.
> Found 1 clusters in hypercube 76.
> Found 1 clusters in hypercube 77.
Cube_78 is empty.
> Found 1 clusters in hypercube 79.
> Found 1 clusters in hypercube 80.
Cube_81 is empty.
Cube_82 is empty.
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.
> Found 1 clusters in hypercube 95.
> Found 1 clusters in hypercube 96.
Cube_97 is empty.
Cube_98 is empty.
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.
Cube_106 is empty.
Cube_107 is empty.
Cube_108 is empty.
Cube_109 is empty.
> Found 1 clusters in hypercube 110.
> Found 1 clusters in hypercube 111.
> Found 1 clusters in hypercube 112.
> Found 1 clusters in hypercube 113.
Cube_114 is empty.
Cube_115 is empty.
Cube_116 is empty.
Cube_117 is empty.
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.
> Found 1 clusters in hypercube 128.
> Found 1 clusters in hypercube 129.
Cube_130 is empty.
Cube_131 is empty.
Cube_132 is empty.
Cube_133 is empty.
Cube_134 is empty.
Cube_135 is empty.
> Found 1 clusters in hypercube 136.
> Found 1 clusters in hypercube 137.
> Found 1 clusters in hypercube 138.
Cube_139 is empty.
Cube_140 is empty.
> Found 1 clusters in hypercube 141.
> Found 1 clusters in hypercube 142.
Cube_143 is empty.
Cube_144 is empty.
Cube_145 is empty.
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.
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.
Cube_159 is empty.
Cube_160 is empty.
> Found 1 clusters in hypercube 161.
> Found 1 clusters in hypercube 162.
> Found 1 clusters in hypercube 163.
Cube_164 is empty.
Cube_165 is empty.
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.
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.
Cube_184 is empty.
Cube_185 is empty.
> Found 1 clusters in hypercube 186.
> Found 1 clusters in hypercube 187.
> Found 1 clusters in hypercube 188.
Cube_189 is empty.
Cube_190 is empty.
> Found 1 clusters in hypercube 191.
> Found 1 clusters in hypercube 192.
> Found 1 clusters in hypercube 193.
Cube_194 is empty.
Cube_195 is empty.
Cube_196 is empty.
Cube_197 is empty.
Cube_198 is empty.
Cube_199 is empty.
> 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.
> Found 1 clusters in hypercube 210.
> Found 1 clusters in hypercube 211.
> Found 1 clusters in hypercube 212.
Cube_213 is empty.
Cube_214 is empty.
> Found 1 clusters in hypercube 215.
> Found 1 clusters in hypercube 216.
> Found 1 clusters in hypercube 217.
Cube_218 is empty.
Cube_219 is empty.
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.
> Found 1 clusters in hypercube 233.
> Found 1 clusters in hypercube 234.
> Found 1 clusters in hypercube 235.
> Found 1 clusters in hypercube 236.
Cube_237 is empty.
Cube_238 is empty.
Cube_239 is empty.
> Found 1 clusters in hypercube 240.
> Found 1 clusters in hypercube 241.
Cube_242 is empty.
> Found 1 clusters in hypercube 243.
Cube_244 is empty.
Cube_245 is empty.
Cube_246 is empty.
> Found 1 clusters in hypercube 247.
> Found 1 clusters in hypercube 248.
> Found 1 clusters in hypercube 249.
Cube_250 is empty.
Cube_251 is empty.
Cube_252 is empty.
> Found 1 clusters in hypercube 253.
> Found 1 clusters in hypercube 254.
> Found 1 clusters in hypercube 255.
> Found 1 clusters in hypercube 256.
> Found 1 clusters in hypercube 257.
> Found 1 clusters in hypercube 258.
> Found 1 clusters in hypercube 259.
> Found 1 clusters in hypercube 260.
Cube_261 is empty.
Cube_262 is empty.
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.
> Found 1 clusters in hypercube 271.
> Found 1 clusters in hypercube 272.
Cube_273 is empty.
Cube_274 is empty.
> Found 1 clusters in hypercube 275.
> Found 1 clusters in hypercube 276.
> Found 1 clusters in hypercube 277.
Cube_278 is empty.
Cube_279 is empty.
Cube_280 is empty.
> Found 1 clusters in hypercube 281.
> Found 1 clusters in hypercube 282.
Cube_283 is empty.
Cube_284 is empty.
> Found 1 clusters in hypercube 285.
> Found 1 clusters in hypercube 286.
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.
> Found 1 clusters in hypercube 294.
> Found 1 clusters in hypercube 295.
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.
Cube_306 is empty.
Cube_307 is empty.
Cube_308 is empty.
Cube_309 is empty.
> Found 1 clusters in hypercube 310.
> Found 1 clusters in hypercube 311.
> Found 1 clusters in hypercube 312.
Cube_313 is empty.
> Found 1 clusters in hypercube 314.
> Found 1 clusters in hypercube 315.
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.
> Found 1 clusters in hypercube 324.
> Found 1 clusters in hypercube 325.
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.
Cube_333 is empty.
> Found 1 clusters in hypercube 334.
Cube_335 is empty.
> Found 1 clusters in hypercube 336.
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.
Cube_344 is empty.
Cube_345 is empty.
> Found 1 clusters in hypercube 346.
> Found 1 clusters in hypercube 347.
> Found 1 clusters in hypercube 348.
> Found 1 clusters in hypercube 349.
Cube_350 is empty.
Cube_351 is empty.
Cube_352 is empty.
> Found 1 clusters in hypercube 353.
> Found 1 clusters in hypercube 354.
> Found 1 clusters in hypercube 355.
Cube_356 is empty.
Cube_357 is empty.
> Found 1 clusters in hypercube 358.
Cube_359 is empty.
Cube_360 is empty.
> Found 1 clusters in hypercube 361.
> Found 1 clusters in hypercube 362.
> Found 1 clusters in hypercube 363.
> Found 1 clusters in hypercube 364.
Cube_365 is empty.
Cube_366 is empty.
> Found 1 clusters in hypercube 367.
Cube_368 is empty.
Cube_369 is empty.
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.
Cube_375 is empty.
Cube_376 is empty.
Cube_377 is empty.
Cube_378 is empty.
Cube_379 is empty.
Cube_380 is empty.
Cube_381 is empty.
Cube_382 is empty.
Cube_383 is empty.
> Found 1 clusters in hypercube 384.
> Found 1 clusters in hypercube 385.
> Found 1 clusters in hypercube 386.
Cube_387 is empty.
> Found 1 clusters in hypercube 388.
> Found 1 clusters in hypercube 389.
> Found 1 clusters in hypercube 390.
> Found 1 clusters in hypercube 391.
> Found 1 clusters in hypercube 392.
Cube_393 is empty.
Cube_394 is empty.
Cube_395 is empty.
Cube_396 is empty.
Cube_397 is empty.
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.
> Found 1 clusters in hypercube 407.
> Found 1 clusters in hypercube 408.
> Found 1 clusters in hypercube 409.
> Found 1 clusters in hypercube 410.
Cube_411 is empty.
> Found 1 clusters in hypercube 412.
> Found 1 clusters in hypercube 413.
Cube_414 is empty.
Created 342 edges and 153 nodes in 0:00:00.177341.
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
scikit-tda/kepler-mapper