python plotly - 旋转辅助 X 轴标签

python plotly - rotating secondary X axis labels

假设我创建了这样一个情节图:

x = [['A','A','B','B'], ['X','Y','X','Y']]
y = [1,2,3,2]
fig = go.Figure()
fig.add_bar(x=x, y=y)
fig.show()

我明白了: 我想旋转辅助 X 标签('A' 和 'B')。我试过了:

fig.update_xaxes(tickangle=45)

但这只会旋转 'X' 和 'Y' 标签。我该怎么做?

根据 plotly 团队的 this discussion,似乎没有实现为多分类轴旋转两个标签的功能,因为如果二级标签是,则很难控制重叠标签长.

在您的情况下,您可能做的最好的事情就是将辅助标签添加为注释。我用不同数量的空格替换了每个唯一标签,这样它们就不会出现,但仍然被 Plotly 解释为另一个类别(例如 'A'' ' 替换,'B' 是替换为 ' ',依此类推...)。

然后,与其将标签放在我们知道它们应该去的地方,不如制作一个可扩展的函数,根据您拥有的辅助标签的数量来确定辅助标签的放置位置。x-labels。它还会在放置标签时旋转标签。

所以我写了一个函数来执行这个解决方法(为了演示,我修改了二级标签的数量以表明它适用于类别和子类别的一般情况):

import plotly.graph_objects as go

## use placeholders so labels don't show up
## map each unique label to a different number of spaces
## extend the labels to show that the solution can be generalized
secondary_labels = ['A','A','A','B','B','C']

label_set = sorted(set(secondary_labels), key=secondary_labels.index)
label_mapping = {label:' '*i for i, label in enumerate(label_set)}
secondary_labels_mapped = [label_mapping[label] for label in secondary_labels]

x = [secondary_labels_mapped, ['X','Y','Z','X','Y','X']]
y = [1,2,3,4,2,4]

## source: https://www.geeksforgeeks.org/python-program-to-find-cumulative-sum-of-a-list/
def cumsum(lists):
    cu_list = []
    length = len(lists)
    cu_list = [sum(lists[0:x:1]) for x in range(0, length+1)]
    return cu_list[1:]

relative_lengths = {}
start_loc = []
for label in label_set:
    relative_lengths[label] = secondary_labels.count(label) / len(secondary_labels)

## get the length of each interval
end_lens = list(relative_lengths.values())
start_lens = [0] + end_lens[:-1]

end_locs = cumsum(end_lens)
start_locs = cumsum(start_lens)

annotation_locs = [(start + end) / 2 for start, end in zip(start_locs, end_locs)]

fig = go.Figure()
fig.add_bar(x=x, y=y)

for label, loc in zip(label_set,annotation_locs):
    fig.add_annotation(
        x=loc,
        y=0,
        xref="paper",
        yref="paper",
        text=label,
        showarrow=False,
    )

## rotate both the annotation angle and the xaxes angles by 45 degrees
## shift annotations down so they display on the axes
fig.update_annotations(textangle=45, yshift=-40)
fig.update_xaxes(tickangle=45)

fig.show()