Source code for ava.plotting.tooltip_plot

"""
Plot a syllable projection with spectrograms appearing as tooltips.

"""
__date__ = "March 2019 - December 2020"

from bokeh.plotting import figure, output_file, show, ColumnDataSource
from bokeh.models import HoverTool
from bokeh.models.glyphs import ImageURL
import matplotlib.pyplot as plt
plt.switch_backend('agg')
import os
import numpy as np
import umap



[docs]def tooltip_plot_DC(dc, embedding_type='latent_mean_umap', output_dir='html', \ num_imgs=1000, title="", n=30000, grid=False, img_format='.jpg'): """ DataContainer version of `tooltip_plot`. Parameters ---------- dc : ava.data.data_container.DataContainer DataContainer object embedding_type : str, optional Defaults to ``'latent_mean_umap'``. output_dir : str, optional Directory where html and jpegs are written. Deafaults to ``'temp'``. num_imgs : int, optional Number of points with tooltip images. Defaults to ``1000``. title : str, optional Title of plot. Defaults to ``''``. n : int, optional Total number of scatterpoints to plot. Defaults to ``30000``. grid : bool, optional Show x and y grid? Defaults to ``False``. img_format : str, optional Filetype for tooltip spectrograms. Defaults to ``'.jpg'``. """ embedding = dc.request('latent_mean_umap') images = dc.request('specs') output_dir = os.path.join(dc.plots_dir, output_dir) print("writing tooltip plot to", output_dir) tooltip_plot(embedding, images, output_dir=output_dir, num_imgs=num_imgs, \ title=title, n=n, grid=grid)
[docs]def tooltip_plot(embedding, images, output_dir='temp', num_imgs=10000, title="", n=30000, grid=False): """ Create a scatterplot of the embedding with spectrogram tooltips. TO DO ----- * Set the aspect ratio to 1 Parameters ---------- embedding : numpy.ndarray The scatterplot coordinates. Shape: (num_points, 2) images : numpy.ndarray A spectrogram image for each scatter point. Shape: (num_points, height, width) output_dir : str, optional Directory where html and jpegs are written. Deafaults to "temp". num_imgs : int, optional Number of points with tooltip images. Defaults to 10000. title : str, optional Title of plot. Defaults to ''. n : int, optional Total number of scatterpoints to plot. Defaults to 30000. grid : bool, optional Show x and y grid? Defaults to `False`. """ # Shuffle the embedding and images. np.random.seed(42) perm = np.random.permutation(len(embedding)) np.random.seed(None) embedding = embedding[perm] images = images[perm] n = min(len(embedding), n) num_imgs = min(len(images), num_imgs) _write_images(embedding, images, output_dir=output_dir, num_imgs=num_imgs, n=n) output_file(os.path.join(output_dir, "main.html")) source = ColumnDataSource( data=dict( x=embedding[:num_imgs,0], y=embedding[:num_imgs,1], imgs = ['./'+str(i)+'.jpg' for i in range(num_imgs)], ) ) source2 = ColumnDataSource( data=dict( x=embedding[num_imgs:,0], y=embedding[num_imgs:,1], ) ) p = figure(plot_width=800, plot_height=600, title=title) p.scatter('x', 'y', size=3, fill_color='blue', fill_alpha=0.1, source=source2) tooltip_points = p.scatter('x', 'y', size=5, fill_color='red', source=source) hover = HoverTool( renderers=[tooltip_points], tooltips=""" <div> <div> <img src="@imgs" height="128" alt="@imgs" width="128" style="float: left; margin: 0px 0px 0px 0px;" border="1" ></img> </div> </div> """ ) p.add_tools(hover) p.title.align = "center" p.title.text_font_size = "25px" p.axis.visible = grid p.xgrid.visible = grid p.ygrid.visible = grid show(p)
def _save_image(data, filename): """https://fengl.org/2014/07/09/matplotlib-savefig-without-borderframe/""" sizes = np.shape(data) height = float(sizes[0]) width = float(sizes[1]) fig = plt.figure() fig.set_size_inches(width/height, 1, forward=False) ax = plt.Axes(fig, [0., 0., 1., 1.]) ax.set_axis_off() fig.add_axes(ax) ax.imshow(data, cmap='viridis', origin='lower') plt.savefig(filename, dpi=height) plt.close('all') def _write_images(embedding, images, output_dir='temp/', num_imgs=100, n=30000): if not os.path.exists(output_dir): os.makedirs(output_dir) X = embedding[:,0] Y = embedding[:,1] for i in range(num_imgs): _save_image(images[i], os.path.join(output_dir, str(i) + '.jpg')) return embedding if __name__ == '__main__': pass ###