I have a single-channel image where each integer pixel value maps to a string. For example 5 -> 'person'. I'm trying to create an interactive image where hovering over a pixel will display it's corresponding string.
I figured using plotly heatmaps might be the way to do this. The issues I'm having are:
z_text
seems like a bad workaround, but setting annotation_text=None
doesn't seem to work.Can anyone help me out here? Here's what I've got:
import numpy as np
import plotly.graph_objs as go
from plotly.offline import download_plotlyjs, init_notebook_mode, plot, iplot
init_notebook_mode(connected=True)
import plotly.figure_factory as ff
z = np.random.randint(0,6, size=(10, 10))
z_text = np.full(z.shape, '', dtype=str)
d = {0:'a', 1:'b', 2:'c', 3:'d', 4:'e', 5:'f'}
class_mat = np.vectorize(d.get)(z)
fig = ff.create_annotated_heatmap(z, annotation_text=z_text, text=class_mat, hoverinfo='text', colorscale='Viridis', )
fig.layout.title = 'Semantic Segmentation'
iplot(fig, filename='annotated_heatmap_text')
And here's what it currently looks like:
Also if a plotly heatmap is not the best way to go about this I'd love to hear any alternatives!
Note: I'm currently displaying inside jupyterlab.
I'm not sure if I've gotten every detail correct here, but the code in the snippet below will produce the following plot in a Jupyter Notebook. The line that handles the aspect ratio is:
fig['layout']['yaxis']['scaleanchor']='x'
You can also use:
fig.update_layout(yaxis = dict(scaleanchor = 'x'))
Plot 1:
Plot 2:
Just make sure to include:
fig.update_layout(plot_bgcolor='rgba(0,0,0,0)')
Or else you'll end up with this:
Code 1 - My edits to your sample:
fig.data[0]['hoverinfo'] = 'all'
fig['layout']['yaxis']['scaleanchor']='x'
fig['layout']['xaxis']['gridcolor'] = 'rgba(0, 0, 0, 0)'
fig['layout']['yaxis']['gridcolor'] = 'rgba(0, 0, 0, 0)'
fig['layout']['yaxis']['color'] = 'rgba(0, 0, 0, 0)'
Code 2 - The whole thing for an easy copy&paste:
import numpy as np
import plotly.graph_objs as go
from plotly.offline import download_plotlyjs, init_notebook_mode, plot, iplot
init_notebook_mode(connected=True)
import plotly.figure_factory as ff
#%qtconsole
z = np.random.randint(0,6, size=(10, 10))
z_text = np.full(z.shape, '', dtype=str)
d = {0:'a', 1:'b', 2:'c', 3:'d', 4:'e', 5:'f'}
class_mat = np.vectorize(d.get)(z)
fig = ff.create_annotated_heatmap(z, annotation_text=z_text,
text=class_mat, hoverinfo='text', colorscale='Viridis',
# x = list('ABCDEFGHIJ'),
# y = list('ABCDEFGHIJ')
)
fig.layout.title = 'Semantic Segmentation'
# My suggestions:
fig.data[0]['hoverinfo'] = 'all'
fig['layout']['yaxis']['scaleanchor']='x'
fig['layout']['xaxis']['gridcolor'] = 'rgba(0, 0, 0, 0)'
fig['layout']['yaxis']['gridcolor'] = 'rgba(0, 0, 0, 0)'
fig['layout']['yaxis']['color'] = 'rgba(0, 0, 0, 0)'
fig.update_layout(plot_bgcolor='rgba(0,0,0,0)')
fig.show()
Speed:
Even this small figure takes some time to plot, but so far I do not have any suggestions on how to speed things up.