Treemap Text Label formatting - number to $xx.xxB

Trying to do a treemap, how can format the text template to make the number as $30.00B. the commented texttemplate does not work and I am not sure how this should be done correctly.

import plotly.graph_objects as go

values = [0, 11000000000, 12000000000, 13000000000, 14000000000, 15000000000, 20000000000, 30000000000]
labels = ["container", "A1", "A2", "A3", "A4", "A5", "B1", "B2"]
parents = ["", "container", "container", "container", "A2", "A1", "container", "B1"]

fig = go.Figure(go.Treemap(
    labels = labels,
    values = values,
    parents = parents,
    textinfo = "label+value+percent root",
    # texttemplate='%{labels: } <br> $%{values: 0.2s} <br> %{percent root}',
    marker_colorscale = 'Blues',
    textposition = 'middle center',
    textfont = dict(family="Arial", size=30, color = '#FFFFFF'), # white color    
))

fig.update_layout(margin = dict(t=50, l=25, r=25, b=25))
fig.show()

@empet do you have time to take a look of this?

@DennisZ
Inspecting print(help(go.Treemap.texttemplate)) we get:

    Template string used for rendering the information text that
    appear on points. Note that this will override `textinfo`.
    Variables are inserted using %{variable}, for example "y:
    %{y}". Numbers are formatted using d3-format's syntax
    %{variable:d3-format}, for example "Price: %{y:$.2f}".
    https://github.com/d3/d3-format/tree/v1.4.5#d3-format for
    details on the formatting syntax. Dates are formatted using
    d3-time-format's syntax %{variable|d3-time-format}, for example
    "Day: %{2019-01-01|%A}". https://github.com/d3/d3-time-
    format/tree/v2.2.3#locale_format for details on the date
    formatting syntax. Every attributes that can be specified per-
    point (the ones that are `arrayOk: true`) are available.
    variables `currentPath`, `root`, `entry`, `percentRoot`,
    `percentEntry`, `percentParent`, `label` and `value`.

Hence according to this information
textemplate should be defined as follows:

texttemplate="%{labels}<br>%{values: $.2s}<br>%{percent root}"

but it doesn’t work. @archmoj could you, please, suggest what’s wrong with this definition?

1 Like

@empet @archmoj Thanks for the help. I noticed that

Every attributes that can be specified per-
    point (the ones that are `arrayOk: true`) are available.
    variables `currentPath`, `root`, `entry`, `percentRoot`,
    `percentEntry`, `percentParent`, `label` and `value`.

If I changed to the following

    texttemplate='%{label: } <br> $%{value: 0.2s} <br> %{percentRoot}',

the chart becomes the following. My question is that a) why the label does not show correctly? b) how can I change the unit G to B (B=Billions)? Let me know and thanks.

This means that the information displayed by help(go.Treemap.texttemplate) is not the right one, because the $ is given in front of the data format: Price: %{y:$.2f}"

With this definition:

 texttemplate='%{label: labels } <br> $%{value: 0.2s} <br> %{percentRoot}',

I got:

It seems that now .2s has no effect.

@empet tried the following and 0.2s works now but how to make showing B instead of G?

    texttemplate='%{label} <br> $%{value: 0.2s} <br> %{percentRoot}',

What plotly version are you running? With your settings that worked for you, I get a plot that displays verbatim the texttemplate string.

my version plotly==4.14.3

@empet I tried to add a value string list for the text but it does not really work, not sure how to replace G by B without using the customized string list.

import plotly.graph_objects as go

values = [0, 11000000000, 12000000000, 13000000000, 14000000000, 15000000000, 20000000000, 30000000000]
labels = ["container", "A1", "A2", "A3", "A4", "A5", "B1", "B2"]
parents = ["", "container", "container", "container", "A2", "A1", "container", "B1"]

value_list = list()
for i in range(0, len(values)):
    label_text = "{:.2f}".format(values[i]/10**9)
    value_list.append(f'${label_text}B')
print(value_list)

fig = go.Figure(go.Treemap(
    labels = labels,
    values = values,
    parents = parents,
    text = value_list,
    textinfo = "label+value+percent root",
    texttemplate='%{label} <br> %{value: text} <br> %{percentRoot}',
    # texttemplate='%{label} <br> $%{value: 0.2s} <br> %{percentRoot}',
    marker_colorscale = 'Blues',
    textposition = 'middle center',
    textfont = dict(family="Arial", size=30, color = '#FFFFFF'), # white color    
))

fig.update_layout(margin = dict(t=50, l=25, r=25, b=25))
fig.show()

I dont think you’re able to. the S should stand for scientific notation, for which after Mega (not million) would come Giga. I was looking for a similar fix, but dont think it’s out there as any pre-built format.

@etjkai Thanks for the comment. I tried to define a function to let it read for value in annotation but it does not read it correctly… see the code right above your answer.

Yep - of course a customized solution would work, but I guess as you’ve noted, there’re quite a few edge cases to take care of. Another solution that I chanced upon is using humanize · PyPI, check if out to see if meets your needs.

Just wanted to clarify that I dont think there’s an existing d3.js number formatting that fit your needs. Happy to be proven wrong someday :stuck_out_tongue:

1 Like

@empet @etjkai Thanks for the discussion here and I guess treemap module regarding notation still has some bugs for the version I am using currently (plotly==4.14.3) as of post date. Hope in the near future, this can be fixed soon.