简体   繁体   中英

Python Plotly - Annotated Heatmap - Adding layout

I found two different ways of making a heatmap in Plotly, one in which it annotates the heatmap, the other just uses a colorbar.

Annotation:

dfreverse = df_hml.values.tolist()
dfreverse.reverse()

colorscale = [[0,'#FFFFFF'],[1, '#F1C40F']]

x = [threeYr,twoYr,oneYr,Yr]
y = ['March', 'February', 'January', 'December', 'November', 'October', 'September', 'August', 'July', 'June', 'May', 'April']
z = dfreverse


z_text = np.around(z, decimals=2) # Only show rounded value (full value on hover)

fig = ff.create_annotated_heatmap(z, x=x, y=y,annotation_text=z_text, colorscale=colorscale, hoverinfo='z')


# Make text size smaller
for i in range(len(fig.layout.annotations)):
        fig.layout.annotations[i].font.size = 9


plotly.offline.iplot(fig, filename='annotated_heatmap_numpy')

在此处输入图片说明

Colorbar:

dfreverse = df_hml.values.tolist()
dfreverse.reverse()

colorscale = [[0, '#454D59'],[0.5, '#FFFFFF'], [1, '#F1C40F']]

x = [threeYr,twoYr,oneYr,Yr]
y = ['March', 'February', 'January', 'December', 'November', 'October', 'September', 'August', 'July', 'June', 'May', 'April']
z = dfreverse

hovertext = list()
for yi, yy in enumerate(y):
    hovertext.append(list())
    for xi, xx in enumerate(x):
        hovertext[-1].append('Count: {}<br />{}<br />{}'.format(z[yi][xi],yy, xx))

data = [plotly.graph_objs.Heatmap(z=z,
                                  colorscale=colorscale,
                                  x=x,
                                  y=y,
                                  hoverinfo='text',
                                  text=hovertext)]

layout = go.Layout(
    autosize=False,
    font=Font(
        family="Gill Sans MT",
        size = 11
    ),
    width=700,
    height=450,
    margin=go.Margin(
        l=150,
        r=160,
        b=50,
        t=100,
        pad=3
    ),
        xaxis=dict(
        title='',
        showgrid=False,
        titlefont=dict(
           # family='Gill sans, monospace',
            size=12,
            #color='#7f7f7f'
        ),
        showticklabels=True,
        tickangle=25,
        tickfont=dict(
            family="Gill Sans MT",
            size=12,
            color='black'
        ),
    ),
    yaxis=dict(
        title='',
        showgrid=False,
        titlefont=dict(
            #family='Gill sans',
            #size=12,
            #color='#7f7f7f'
        ),
        showticklabels=True,
        tickangle=25,
        tickfont=dict(
            family="Gill Sans MT",
            size=12,
            color='black'
        ),
)
)

fig = plotly.graph_objs.Figure(data=data, layout=layout)
plotly.offline.iplot(fig,config={"displayModeBar": False},show_link=False,filename='pandas-heatmap')

在此处输入图片说明

The actual question

I want to produce the heatmap with the annotation (1st chart) but be able to change the font and font size of the x and y axis through I presume a layout. However the Annotation Heatmap code doesnt seem to like me putting a layout in it. Is this possible?

The ff.create_annotated_heatmap doesn't directly accept a layout as a keyword argument, but you can update the layout of the fig it produces:

fig = ff.create_annotated_heatmap(z, x=x, y=y,annotation_text=z_text, colorscale=colorscale, hoverinfo='z')

fig.layout.update(
  go.Layout(
    autosize=False,
    font=Font(
      family="Gill Sans MT",
      size = 11
    )
  )
)

plotly.offline.iplot(fig, filename='annotated_heatmap_numpy')

This way you don't have to pass each of the values separately, especially in the case you have an existing layout that you want to re-use.

I found this answer , which tells how to to alter layout of x axis:

I can't test it, but reading https://plot.ly/python/reference/#layout-yaxis-titlefont suggests this code:

fig = ff.create_annotated_heatmap(z, x=x, y=y,annotation_text=z_text, colorscale=colorscale, hoverinfo='z')

# Altering x axis
fig['layout']['xaxis']['titlefont']['family'] = "Arial"
fig['layout']['xaxis']['titlefont']['size'] = 14

# (same procedure for 'yaxis')...

plotly.offline.iplot(fig, filename='annotated_heatmap_numpy')

I've played with the animation methods, therefore, I had to annotate the heatmap using the go.Heatmap directly. Here is my solution:

from functools import reduce
from itertools import product
z = [[1, 2, 5],
     [2, 5, 1],
     [5, 1, 2]]

def get_att(Mx):
    att=[]
    a, b = len(Mx), len(Mx[0])
    flat_z = reduce(lambda x,y: x+y, Mx) #Mx.flat if you deal with numpy
    coords = product(range(a), range(b))
    for pos, elem in zip(coords, flat_z):
        att.append({'font': {'color': '#FFFFFF'},
                    'showarrow': False,
                    'text': str(elem),
                    'x': pos[1],
                    'y': pos[0]})
    return att
        
fig = go.Figure(data=[go.Heatmap(z=z)])
fig.update_layout(annotations=get_att(z))
fig.show()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM