抑制绘图子图中的y轴标签,注释未对齐
Posted
技术标签:
【中文标题】抑制绘图子图中的y轴标签,注释未对齐【英文标题】:Suppress y axis label in plotly subplot, annotation misalignment 【发布时间】:2020-10-21 06:09:19 【问题描述】:我尝试将 2 个热图连接在一起,一个包含每周数据,另一个包含 6W/YTD 信息。我将它们分开,这样它们的颜色就不会歪斜。
当它们放在一个子图中时,右侧的 y 轴标签是左侧的第一行标签
我想删除那个 yaxis 标签,并尝试通过 fig.update_yaxes(title=''/None/False)
以及 title_text
参数,我也尝试通过 fig['layout']['scenes']['yaxis2']['title'] = ''/None/False
访问它。似乎有很多资源(包括官方文档)显示了如何更改单个数字,这可以通过我的代码通过
fig1['layout']['yaxis']['title']='This works with a single plot'
fig1.show()
不幸的是,当fig2
被添加到子图中时,它不会继续存在。我不确定这项任务是如何进行的。我已经查看了 JSON 结构,但没有看到任何分配,我还在他们的文档中挖掘了该结构,看看是否有可以覆盖或设置的东西。有人可以帮我弄清楚如何隐藏fig2
yaxis 标签吗?询问如何手动设置可能更准确,但尽管如此。
*编辑* 我仔细查看了注释。数字注释是用这个位设置的
annotations=wow_annot+totals_annot
这些都是基于
wow['data_labels'] = int_to_str(wow['data'])
totals['data_labels'] = int_to_str(totals['data'])
这只是二维整数数组。检查每个图中“A”的注释,它们作为子图添加到的图是唯一包含“A”的图
(Pdb) [i for i in fig1.layout.annotations if i.text == 'A']
[]
(Pdb) [i for i in fig2.layout.annotations if i.text == 'A']
[]
(Pdb) [i for i in fig.layout.annotations if i.text == 'A']
[layout.Annotation(
'font': 'size': 16,
'showarrow': False,
'text': 'A',
'textangle': 90,
'x': 0.98,
'xanchor': 'left',
'xref': 'paper',
'y': 0.5,
'yanchor': 'middle',
'yref': 'paper'
)]
基于此,这可以很容易地通过像这样覆盖注释来追溯“解决”
new_annot = []
for i in fig.layout.annotations:
if i.text == wow['y_labels']['labels'][0]:
i.text = ''
new_annot.append(i)
fig.update_layout(annotations=new_annot)
这工作,但感觉非常挑剔,我仍然想知道这是如何应该用情节来完成的。这种方法感觉可能会产生意想不到的效果,具体取决于应用程序。
经过仔细检查,我还意识到底行的前 2 列没有任何注释,尽管它们在原始图中有注释
(Pdb) fig1.layout.annotations[:2]
(layout.Annotation(
'font': 'color': 'black', 'showarrow': False, 'text': '0', 'x': 'W21', 'xref': 'x', 'y': 'A', 'yref': 'y'
), layout.Annotation(
'font': 'color': 'black', 'showarrow': False, 'text': '0', 'x': 'W22', 'xref': 'x', 'y': 'A', 'yref': 'y'
))
我不确定是我遗漏了什么,还是我的方法在设置注释时不正确
Checking `wow_annot+totals_annot` for `W21:A` annotation
layout.Annotation(
'font': 'color': 'black', 'showarrow': False, 'text': '0', 'x': 'W21', 'xref': 'x', 'y': 'A', 'yref': 'y'
)
Checking the final `fig` for `W21:A` annotation
> d:\test_subplots.py(178)<module>()
-> fig.show()
(Pdb) len([i for i in totals_annot if i.y == 'A'])
2
(Pdb) len([i for i in wow_annot if i.y == 'A'])
6
(Pdb) len([i for i in totals_annot+wow_annot if i.y == 'A'])
8
(Pdb) len([i for i in fig.layout.annotations if i.y == 'A'])
6
我将保持原样,因为这篇文章变得很麻烦,但有一个问题:1)注释和 2)图 2 的 y 标题;我觉得他们必须是相关的,虽然我不知道这是怎么发生的
我在下面分离了我的代码,可以使用粘贴 here。
进口
# Success Criteria for this exercise is a subplot containing 2 Heatmaps side by side in the same Figure
from pdb import set_trace
from covidDash.plot_handlers.colorscales import bone_r # this is a custom derived from matplotlib
from plotly.subplots import make_subplots
import plotly.figure_factory as ff
import plotly.graph_objects as go
数据准备
# DATA PREP SECTION
# wow Heatmap data
wow = 'x_labels' : 'name' : 'Week',
'labels' : ['W21', 'W22', 'W23', 'W24', 'W25', 'W26']
,
'y_labels' : 'name' : 'Site',
'labels' : ['A', 'B', 'C', 'D', 'E', 'F', 'G']
,
'data' : [
[0, 0, 1, 0, 0, 0],
[0, 0, 3, 1, 0, 0],
[0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 1],
[0, 0, 0, 0, 0, 0],
[0, 0, 1, 0, 0, 0],
[0, 0, 0, 0, 0, 0]
],
'data_labels' : []
# 6w and YTD Heatmap data
totals = 'x_labels' : 'name' : 'Week',
'labels' :['6W', 'YTD' ]
,
'y_labels' : wow['y_labels'],
'data' : [
[1, 16],
[4, 8],
[0, 1],
[1, 12],
[0, 5],
[1, 17],
[0, 1]
],
'data_labels' : []
# this function is simply a base func for now
def int_to_str(arr2d):
"""base function for handling data to label conversion
Args:
arr2d (list): a 2D array with numeric values
Returns:
r_data (list): a 2D array with values converted into strings
"""
r_data = []
for row in arr2d:
new_row = []
[new_row.append(str(n)) for n in row]
r_data.append(new_row)
return r_data
wow['data_labels'] = int_to_str(wow['data'])
totals['data_labels'] = int_to_str(totals['data'])
情节准备
# PLOT PREP SECTION
# colorbar placement
wow_cbar=
'x' : 1.0,
'title' :
'text' : 'Wow',
'side' : 'right'
total_cbar =
'x' : 1.05,
'title' :
'text' : 'Totals',
'side' : 'right'
# xaxis conf
xaxis_conf='rangeslider': 'visible': True,
'type' : 'category',
'side' : 'top'
创建和连接图形
# week over week figure
fig1 = ff.create_annotated_heatmap(x=wow['x_labels']['labels'],
y=wow['y_labels']['labels'],
z=wow['data'],
colorscale=bone_r,
font_colors=['black','white'],
showscale=True,
annotation_text=wow['data_labels'],
colorbar=wow_cbar,
name='Wow'
)
# 6W and YTD
fig2 =ff.create_annotated_heatmap(x=totals['x_labels']['labels'],
y=totals['y_labels']['labels'],
z=totals['data'],
colorscale=bone_r,
font_colors=['black','white'],
showscale=True,
annotation_text=totals['data_labels'],
colorbar=total_cbar,
name='Totals',
)
# SUBPLOT PREP SECTION
# base subplot
fig = make_subplots(
rows=1, cols=2,
shared_yaxes=True,
horizontal_spacing=0,
row_titles=wow['y_labels']['labels'],
# y_title=[wow['y_labels']['name'],
x_title=wow['x_labels']['name'],
column_widths=[0.75, 0.25]
)
# add data
fig.add_trace(fig1.data[0], 1, 1)
fig.add_trace(fig2.data[0], 1, 2)
# apply annotations
wow_annot = list(fig1.layout.annotations)
totals_annot = list(fig2.layout.annotations)
for k in range(len(totals_annot)):
totals_annot[k]['xref'] = 'x2'
totals_annot[k]['yref'] = 'y2'
fig.update_layout(annotations=wow_annot+totals_annot,xaxis=xaxis_conf, xaxis2='side':'top')
set_trace()
fig.show()
【问题讨论】:
【参考方案1】:fig.update_layout(annotations=foo)
出了点问题,我可以通过重新排列直接应用注释来解决此问题
fig.update_layout(xaxis=xaxis_conf, xaxis2='side':'top')
fig['layout']['annotations'] = wow_annot+totals_annot
这使得所有字段都得到正确注释,并且不再分配 y_label。
至于.update_layout
的具体问题是什么,我不确定,但如果yaxis_title=foo
不适合您,这就是解决此问题的方法。
【讨论】:
【参考方案2】:尝试使用update_layout方法的yaxis_title参数:fig.update_layout(annotations=wow_annot+totals_annot,xaxis=xaxis_conf, xaxis2='side':'top', yaxis_title = None)
这是我的 Jupyter 笔记本的输出(忽略颜色图):
【讨论】:
它仍然显示'A' 这很奇怪。它在我的正确显示。您使用的是什么版本的 Plotly? plotly的当前版本是4.8.1 有机会我会再看一遍,如果你弄明白了,请随时answer your own question以上是关于抑制绘图子图中的y轴标签,注释未对齐的主要内容,如果未能解决你的问题,请参考以下文章