Plotly:在热图中通过单元格中间的形状线
Posted
技术标签:
【中文标题】Plotly:在热图中通过单元格中间的形状线【英文标题】:Plotly: Shape lines passing in the middle of the cells in a heatmap 【发布时间】:2021-05-01 11:06:34 【问题描述】:我正在 python 中使用plotly
绘制热图。我想在某些区域周围画一个矩形,我这样做如下:
import plotly.graph_objs as go
import plotly.figure_factory as ff
layout_heatmap = go.Layout(
xaxis=dict(title='Years'),
yaxis=dict(title='Years'),
)
ff_fig = ff.create_annotated_heatmap(x=all_years, y=all_years, z=heatmap, showscale=True,
colorscale='Viridis',)
fig = go.FigureWidget(ff_fig)
fig.layout = layout_heatmap
fig.layout.annotations = ff_fig.layout.annotations
fig['layout']['yaxis']['autorange'] = "reversed"
fig.add_shape(type="rect",
x0=1960, y0=1960, x1=1966, y1=1966,
line=dict(color="red"),
)
fig.add_shape(type="rect",
x0=1967, y0=1967, x1=1970, y1=1970,
line=dict(color="red"),
)
fig.show()
输出如下:
我不希望矩形穿过单元格,我想要这样的效果,但它不起作用:
【问题讨论】:
我的建议最后对你有什么效果? @vestland 嗨,不幸的是我无法让它工作,我很确定你的代码是正确的,但我不知道为什么在我的工作区它不工作。可能是版本问题 好的,感谢您的快速反馈!您是否有机会考虑将我的建议标记为已接受的答案?如果有更好的解决方案出现,这总是可以撤消的。 @vestland 也感谢您提供详细的反馈和代码,它确实有很大帮助。 不客气!当您有机会在更新版本上进行测试时,请务必回来查看。 【参考方案1】:您最好的选择似乎是:
1.将轴类型更改为分类:
fig.update_xaxes(type='category')
fig.update_yaxes(type='category')
2。按位置而不是值放置形状:
fig.add_shape(type="rect",
x0=-0.5, y0=1.5, x1=3.5, y1=5.5,
line=dict(color="blue", width = 4),
)
fig.add_shape(type="rect",
x0=3.5, y0=-0.5, x1=5.5, y1=1.5,
line=dict(color="green", width = 4),
)
剧情:
带有内置 plotly 数据集的完整代码
import plotly.express as px
import plotly.figure_factory as ff
import pandas as pd
df = px.data.stocks()#.tail(50)
df = df.drop(['date'], axis = 1)
dfc = df.corr()
z = dfc.values.tolist()
# change each element of z to type string for annotations
# z_text = [[str(y) for y in x] for x in z]
z_text = [[str(round(y, 1)) for y in x] for x in z]
# df.columns =['2014', '2015', '2016', '2017', '2018', '2019']
df.columns =[1960, 1962, 1964, 1966, 1968, 1970]
# df.columns =['y1960', 'y1962', 'y1964', 'y1966', 'y1968', 'y1970']
# set up figure
fig = ff.create_annotated_heatmap(z, x=list(df.columns),
y=list(df.columns),
annotation_text=z_text, colorscale='agsunset')
# add custom xaxis title
fig.add_annotation(dict(font=dict(color="black",size=14),
x=0.5,
y=-0.15,
showarrow=False,
text="",
xref="paper",
yref="paper"))
# add custom yaxis title
fig.add_annotation(dict(font=dict(color="black",size=14),
x=-0.35,
y=0.5,
showarrow=False,
text="",
textangle=-90,
xref="paper",
yref="paper"))
fig.add_shape(type="rect",
x0=-0.5, y0=1.5, x1=3.5, y1=5.5,
line=dict(color="blue", width = 4),
)
fig.add_shape(type="rect",
x0=3.5, y0=-0.5, x1=5.5, y1=1.5,
line=dict(color="green", width = 4),
)
# adjust margins to make room for yaxis title
fig.update_layout(margin=dict(t=50, l=200))
# add colorbar
fig['data'][0]['showscale'] = True
fig.update_xaxes(type='category')
fig.update_yaxes(type='category')
fig.show()
【讨论】:
谢谢@vestland,但我仍然面临问题。我运行了您粘贴的相同代码,但绘图为空且缩小,并且根本没有任何值。可能是什么问题? @Perl 那么它可能是版本问题。但我会仔细检查我的结果 是的,您粘贴的代码相同。我也认为它是一个版本的东西。如果有任何更新,请告诉我。提前谢谢你。 @Perl 我用新内核仔细检查了一遍。代码在我这边运行良好。 Plotly 版本是'4.12.0'
。
@hans 和 Perl:分类 xaxis 似乎是问题所在。尝试用实际字符串列表替换年份,例如 ['year 1966', 'year 1968'...]以上是关于Plotly:在热图中通过单元格中间的形状线的主要内容,如果未能解决你的问题,请参考以下文章
重叠 yticklabels:是不是可以控制 seaborn 中热图的单元格大小?