Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Plotly: How to set heatmap aspect ratio?

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:

  • It's really slow. If I make my numpy array even (100,100) size it takes minutes to load. I'm thinking it might be because my code is not efficient?
  • I can't figure out how to maintain aspect ratio. So if my image is a size (100,100) numpy array, I'd like the plot to also be (100,100) pixels.
  • using blank values for 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:

enter image description here

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.

like image 793
Austin Avatar asked Mar 06 '19 01:03

Austin


People also ask

How do you resize Plotly?

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.

What does Add_trace do in Plotly?

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.)

How do you increase your Figsize in Plotly?

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.

What is margin in Plotly?

The default values for the margins are 80 pixels on the left, right, and bottom and 100 pixels on the top.


1 Answers

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:

enter image description here

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:

enter image description here

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.

like image 174
vestland Avatar answered Sep 21 '22 21:09

vestland