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.
Automatically Adjust MarginsSet automargin=true (reference) and Plotly will automatically increase the margin size to prevent ticklabels from being cut off or overlapping with axis titles.
Adding TracesNew traces can be added to a graph object figure using the add_trace() method. This method accepts a graph object trace (an instance of go. Scatter , go. Bar , etc.)
One of the best ways to modify the size of the Plotly figure is by adjusting the width and the height parameters. We will start by discussing how to change the height and width parameters using Plotly Express. For example, in the following code, we create a simple line chart using the default Plotly's dimensions.
The default values for the margins are 80 pixels on the left, right, and bottom and 100 pixels on the top.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With