You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何对齐Plotly冰柱图texttemplate中的文本?

问题描述

我有一个带自定义texttemplate的Plotly冰柱图,想要实现文本的正确对齐(用真正的制表位而非&nbsp;),或者直接显示表格。我发现texttemplate支持<br>、&nbsp;、<span style=...>这类HTML元素,但因为设置了textposition="middle center",文本始终无法对齐。

fig.update_traces(
    texttemplate=...,
    textposition="middle center"
)

如何让texttemplate内的文本正确对齐?


已尝试方案

  • HTML表格:尝试用HTML表格,但所有标签都被当作纯字符串显示(直接打印<table>文本)。
  • 统计字符加间隔符:统计字符串长度后为每行生成间隔,但texttemplate不支持Series乘法操作。
  • 格式化字符串对齐:尝试了以下字符串对齐方式:
'{:<20}{:>20}'.format('column1', 'column2') + "<br>" +
'{:<20}{:>20}'.format('column123', 'column234') + "<br>"

但无效,文本还是没对齐。注:这段代码在Jupyter Notebook里能正确对齐文本。


完整代码

import plotly.express as px
import pandas as pd

df = pd.DataFrame({
    "people":           ["First",       "Anne",        "Bob",          "Chris",        "Damian",       "Eve",          "Faith",        "Gabriel",      "Hester",       "Ivy",          "Jacob"],
    "parent":           ["",            "First",       "First",        "First",        "Anne",         "Bob",          "Bob",          "Chris",        "Chris",        "Eve",          "Hester"],
    "Year of birth":    [1900,           1920,          1924,           1929,           1958,           1963,           1967,           1971,           1972,           2000,           2001],
    "Year of death":    [1900,           1933,          1932,           1931,           1958,           1963,           1967,           1971,           1972,           2000,           2001],
    "Place of birth":   ["Amsterdam",   "Rotterdam",   "Den haag",     "Flevoland",    "Almere",       "Groningen",    "Apeldoorn",    "Zaandam",      "Flevoland",    "Assen",         "Amsterdam",],
    "Place of death":   ["New York",    "LA",          "Washington",   "Texas",        "FLorida",      "New Jersey",   "Cansas",       "Wyoming",      "Georgia",      "New York",      "Nabraska",],
    "spouse":           ["Mario",       "Luigi",       "Peach",        "Bowser",       "Toad",         "Toadette",     "-",             "-",           "-",            "-",             "-",],    
    "Cause of death":   ["Fireball",    "0 lives",     "Chupa",        "Spikes",       "Gravity",      "Teammate",     "-",             "-",           "-",            "-",             "-",],    
})

df = df.sort_values("Year of birth")
df['spacer'] = (df["Place of birth"] + df['Place of death']).str.len()

fig = px.icicle(
    df,
    names='people',
    parents='parent',
    width=1000,
    height=1000,
    color="Year of birth",
    color_continuous_scale="YlGnBu_r",
)

fig.update_traces(    
    texttemplate= 
    "<span style='font-size:15pt'>" + df.people + "</span>" + 
    "<br><br>" + 
    df["Place of birth"] + 30*" " + " " + list(map(str, df["Year of birth"])) + "<br>" +
    df["Place of death"] + 30*" " + " " + list(map(str, df["Year of death"])) + "<br>" +
    "Spouse: " + 21*"&nbsp;" + df.spouse + "<br>" +
    "Cause of death: "  + 10*"&nbsp;" + df['Cause of death'] + "<br>" +
    
    f"{'Aaaa' : <20}" + f"{'Bbbbbbbbbb' : <20}" + "<br>" +
    f"{'Aaaaaa' : <20}" + f"{'Bbbbbbbb' : <20}" + "<br>" +
    f"{'Aaaaaaa' : <20}" + f"{'Bbbbbbbbbbbbbbb' : <20}" + "<br>" +
    f"{'A' : <30}" + f"{'Bb' : <20}" + "<br>" +
    
    '{:<20}{:>20}'.format('column1', 'column2') + "<br>" +
    '{:<20}{:>20}'.format('column123', 'column234') + "<br>" +
    '{:<20}{:>20}'.format('c1', 'c2'),
    
    textposition="middle center"
)

fig.update_layout(
    margin = dict(t=10, l=10, r=10, b=10),
    coloraxis=dict(colorbar=dict(orientation='h', y=-0.3)),
)

fig.show()

当前输出效果

当前图表中文本未对齐,各列内容无法整齐排列。


解决方案

方法1:等宽字体+字符串格式化

Plotly默认用非等宽字体,导致字符串格式化对齐失效。给文本模板设置等宽字体,配合逐行格式化即可解决:

fig.update_traces(    
    texttemplate= 
    "<span style='font-size:15pt; font-family: Courier New, monospace'>" + 
    "<span style='font-size:18pt'>" + df.people + "</span>" + 
    "<br><br>" +
    # 逐行格式化出生地与年份
    df.apply(lambda row: '{:<20}{:>10}'.format(row["Place of birth"], row["Year of birth"]), axis=1) + "<br>" +
    # 逐行格式化死亡地与年份
    df.apply(lambda row: '{:<20}{:>10}'.format(row["Place of death"], row["Year of death"]), axis=1) + "<br>" +
    # 配偶行格式化
    df.apply(lambda row: '{:<20}{}'.format("Spouse:", row["spouse"]), axis=1) + "<br>" +
    # 死因行格式化
    df.apply(lambda row: '{:<20}{}'.format("Cause of death:", row["Cause of death"]), axis=1) +
    "</span>",
    textposition="middle center"
)

说明:

  • 用df.apply(axis=1)逐行生成格式化字符串,避开Series操作限制。
  • 等宽字体下,{:<20}这类语法能保证固定宽度,实现列对齐。

方法2:HTML固定宽度容器(非等宽字体适用)

给每列文本设置inline-block类型的固定宽度容器,强制对齐:

fig.update_traces(    
    texttemplate= 
    "<span style='font-size:15pt'>" + 
    "<span style='font-size:18pt'>" + df.people + "</span>" + 
    "<br><br>" +
    # 出生地列固定宽度200px
    df.apply(lambda row: f"<span style='display: inline-block; width: 200px'>{row['Place of birth']}</span><span>{row['Year of birth']}</span>", axis=1) + "<br>" +
    df.apply(lambda row: f"<span style='display: inline-block; width: 200px'>{row['Place of death']}</span><span>{row['Year of death']}</span>", axis=1) + "<br>" +
    df.apply(lambda row: f"<span style='display: inline-block; width: 200px'>Spouse:</span><span>{row['spouse']}</span>", axis=1) + "<br>" +
    df.apply(lambda row: f"<span style='display: inline-block; width: 200px'>Cause of death:</span><span>{row['Cause of death']}</span>", axis=1) +
    "</span>",
    textposition="middle center"
)

说明:

  • display: inline-block让<span>可设置宽度且不换行。
  • 固定宽度容器确保每列对齐,无需依赖等宽字体。

内容的提问来源于stack exchange,提问作者Xtiaan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 16:18:10