简体   繁体   English

在 plotly 中创建具有固定单元格宽度的分组热图

[英]Creating grouped heatmaps with fixed cell width in plotly

I would like to plot several heatmaps on one plotly figure, where the columns of all heatmaps should have the same width (within and across heatmaps).我想 plot 在一个 plotly 图中绘制多个热图,其中所有热图的列应具有相同的宽度(在热图内和热图之间)。 My first idea was to use make_subplots together with go.Heatmap but with this approach the width of each cell changes accordingly to how many columns each subplot has.我的第一个想法是将go.Heatmapmake_subplots一起使用,但通过这种方法,每个单元格的宽度会根据每个子图的列数而变化。 I need it the other way around.我需要相反的方式。 I would like to set a fixed cell width that needs to be automatically determined using the entire width of the whole figure and the overall number of columns.我想设置一个固定的单元格宽度,需要使用整个图形的整个宽度和总列数自动确定。 Another approach would be to use px.imshow where everything is plotted as one big heatmap, and so all columns have the same width.另一种方法是使用px.imshow ,其中所有内容都绘制为一个大热图,因此所有列都具有相同的宽度。 But with this approach, I am not able to plot the titles for each group of columns.但是通过这种方法,我无法 plot 每组列的标题。 This thread is related to this one but I need a solution in Python not R.该线程与相关,但我需要 Python 中的解决方案,而不是 R。

Code to create example data:创建示例数据的代码:

import numpy as np
from numpy.random import default_rng
import pandas as pd
from plotly.subplots import make_subplots
import plotly.graph_objects as go

rng = default_rng(42)

# create example dataframe
n_variates = 2
variables = ['apple','pear', 'orange','mandarin','grapefruit']
sources = ['pome','pome','citrus','citrus','citrus']
variates = np.repeat(list(range(n_variates)),len(variables))
values = rng.random(n_variates * len(variables))
df = pd.DataFrame({'variable':np.tile(variables,n_variates),
                   'source':np.tile(sources,n_variates),
                   'variate':variates,
                   'value':values})

First approach: Using make_subplots and go.Heatmap (Can create titles but cells have different widths):第一种方法:使用make_subplotsgo.Heatmap (可以创建标题,但单元格具有不同的宽度):

# use subplots and go.Heatmap
z_list = []
source_names = []
for source_name,source in df.groupby('source'):
    z = source.pivot(columns=['source','variable'],index='variate',values='value')
    z_list.append(z)
    source_names.append(source_name)

fig = make_subplots(rows=1,cols=len(z_list),
                    subplot_titles=source_names,
                    horizontal_spacing=0,
                    shared_yaxes=True)
for col,z in enumerate(z_list):
    fig.add_trace(go.Heatmap(z=z,x=z.columns.get_level_values(1),coloraxis = "coloraxis"),1,col+1)
    
fig.update_yaxes(dtick=1)
fig.show()

在此处输入图像描述

Second approach: Using px.imshow (Cells have the same width but group titles are missing):第二种方法:使用px.imshow (单元格具有相同的宽度但缺少组标题):

# use px.imshow()
import plotly.express as px
z = df.pivot(columns=['source','variable'],index='variate',values='value')
source_labels,variable_labels = z.columns.get_level_values(0),z.columns.get_level_values(1)
variate_labels = z.index.tolist()
fig = px.imshow(z.values,x=variable_labels,y=variate_labels)
fig.update_xaxes(type='category')
fig.update_yaxes(type='category')
fig.show()

在此处输入图像描述

After much trial and error on my part, I think it would be easiest to add a title to the second example with the annotation feature.经过我的多次尝试和错误,我认为最简单的方法是在第二个示例中添加带有注释功能的标题。

import plotly.express as px

z = df.pivot(columns=['source','variable'], index='variate', values='value')
source_labels,variable_labels = z.columns.get_level_values(0), z.columns.get_level_values(1)
variate_labels = z.index.tolist()
fig = px.imshow(z.values, x=variable_labels, y=variate_labels, text_auto='.2f')

fig.add_annotation(x=0.3, y=1.1, xref='paper', yref='paper', text=df.source.unique()[0], showarrow=False)
fig.add_annotation(x=0.62, y=1.1, xref='paper', yref='paper', text=df.source.unique()[1], showarrow=False)

fig.update_xaxes(type='category')
fig.update_yaxes(type='category')
fig.show()

在此处输入图像描述

If you use the x-axis with the category variable criteria as it is, you get the following But the title is not the center of the group.如果按原样使用带有类别变量标准的 x 轴,您将得到以下内容 但标题不是组的中心。

fig.add_annotation(x=variable_labels[0], y=1.1, xref='x', yref='paper', text=df.source.unique()[0], showarrow=False)
fig.add_annotation(x=variable_labels[3], y=1.1, xref='x', yref='paper', text=df.source.unique()[1], showarrow=False)

在此处输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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