简体   繁体   中英

Correlation Heatmap in Plotly

I have created a lower triangular correlation heatmap using Seaborn that I loved. Now trying to create the same using Plotly. Unfortunately, not being able to fine tune it like I did with Seaborn.

names = ['U', 'V', 'W', 'X', 'Y', 'Z']
r = pd.DataFrame(index = names, columns = names)
r['U'] = np.array([1.0,   0.53,    0.26,  0.63, 0.52, 0.65] )
r['V'] = np.array([0.53,   1.0,   -0.17, 0.83, 1, 0.85])
r['W'] = np.array([0.26,  -0.17,    1.0,  0.04, -0.15, 0.09])
r['X'] = np.array([0.63, 0.83, 0.04, 1, 0.83, 0.80])
r['Y'] = np.array([0.52, 1, -0.15, 0.83, 1, 0.86])
r['Z'] = np.array([0.65, 0.85, 0.09, 0.80, 0.86, 1.0])

print(r)

在此处输入图像描述

import seaborn as sns

# sns.set_theme(style="white")

mask = np.triu(np.ones_like(r, dtype=bool))

# Set up the matplotlib figure
f, ax = plt.subplots(figsize=(11, 9))

# Generate a custom diverging colormap
cmap = sns.diverging_palette(230, 20, n=256, as_cmap=True)

# Draw the heatmap with the mask and correct aspect ratio
sns.heatmap(r, 
            mask=mask, 
            cmap=cmap, 
            vmax=1, 
            vmin = -.25,
            center=0,
            square=True, 
            linewidths=.5,
            annot = True,
            fmt='.2f', 
            annot_kws={'size': 10},
            cbar_kws={"shrink": .75})

plt.title('Asset Correlation Matrix')
plt.tight_layout()
ax.tick_params(axis = 'x', labelsize = 8)
ax.set_ylim(len(corr)+1, -1)
# plt.savefig('corrTax.png', dpi = 600)

plt.show()

在此处输入图像描述

I am trying to create this using Plotly. Here is what I have able to do so far.

mask = np.triu(np.ones_like(r, dtype=bool))
rLT = r.mask(mask)

heat = go.Heatmap(
    z = rLT,
    x = rLT.columns.values,
    y = rLT.columns.values,
    zmin = - 0.25, # Sets the lower bound of the color domain
    zmax = 1,
    xgap = 1, # Sets the horizontal gap (in pixels) between bricks
    ygap = 1,
    colorscale = 'RdBu'
)

title = 'Asset Correlation Matrix'

layout = go.Layout(
    title_text=title, 
    title_x=0.5, 
    width=600, 
    height=600,
    xaxis_showgrid=False,
    yaxis_showgrid=False,
    yaxis_autorange='reversed'
)

fig=go.Figure(data=[heat], layout=layout)
fig.show()

在此处输入图像描述

  • Seaborn colormap that I was create, I want to create something similar in Plotly. How can I do that?
  • I was able to control the axis label sizes.
  • Would love to put values into each box ( annot option in seaborn), with rounding option

Deb. Here it goes the answer for the first of your questions.

Seaborn colormap that I was create, I want to create something similar in Plotly. How can I do that?

You can use of the built-in colorscales in Plotly , which can be set via the parameter colorscale in the Heatmap constructor. Also, you can set Plotly's theme to get rid of the ugly background

import plotly.io as pio
import plotly.express as px
import plotly.graph_objects as go

pio.templates.default = "plotly_white"

go.Heatmap(
    z=corr.mask(mask),
    x=corr.columns,
    y=corr.columns,
    colorscale=px.colors.diverging.RdBu,
    zmin=-1,
    zmax=1
)

虚拟数据集示例

You can use plotly function create_annotated_heatmap from plotly.figure_factory instead of the normal plotly heatmap. This function accepts numpy array instead of the dataframe directly. Official Reference Here is my solution

corr = df.iloc.corr()
mask = np.triu(np.ones_like(corr, dtype=bool))
df_mask = corr.mask(mask)

fig = ff.create_annotated_heatmap(z=df_mask.to_numpy(), 
                                  x=df_mask.columns.tolist(),
                                  y=df_mask.columns.tolist(),
                                  colorscale=px.colors.diverging.RdBu,
                                  hoverinfo="none", #Shows hoverinfo for null values
                                  showscale=True, ygap=1, xgap=1
                                 )

fig.update_xaxes(side="bottom")

fig.update_layout(
    title_text='Heatmap', 
    title_x=0.5, 
    width=1000, 
    height=1000,
    xaxis_showgrid=False,
    yaxis_showgrid=False,
    xaxis_zeroline=False,
    yaxis_zeroline=False,
    yaxis_autorange='reversed',
    template='plotly_white'
)

# NaN values are not handled automatically and are displayed in the figure
# So we need to get rid of the text manually
for i in range(len(fig.layout.annotations)):
    if fig.layout.annotations[i].text == 'nan':
        fig.layout.annotations[i].text = ""

fig.show()

在此处输入图像描述

You can use zmin and zmax as speciifed by @ottovon

Basic heatmap can also be used but annotations need to be done manually by specifying some function, I presume.

For rounding up annotation refer to this Plotly: How to round display text in annotated heatmap but keep full format on hover? thread.

Also, you can refer the Official Docs for the sizing of the xticks and the same can be done for yticks. I have not practically implemented them but they should work fine.

Easiest way I've found to remove top triangle in view

# Correlation
df_corr = data.corr().round(1)  
# Mask to matrix
mask = np.zeros_like(df_corr, dtype=bool)
mask[np.triu_indices_from(mask)] = True
# Viz
df_corr_viz = df_corr.mask(mask).dropna(how='all').dropna('columns', how='all')
fig = px.imshow(df_corr_viz, text_auto=True)
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