plotly / plotly.js

Open-source JavaScript charting library behind Plotly and Dash
https://plotly.com/javascript/
MIT License
16.82k stars 1.85k forks source link

enable formatting numbers with natural language suffixes, k(ilo), M(illion), B(illion) #6091

Open soerenwolfers opened 2 years ago

soerenwolfers commented 2 years ago

Plotly doesn't currently let me format numbers, e.g. in hover templates, in "human" or "business" form, by which I mean essentially SI representation but with the suffix replacements k->k(ilo) M->M(illion), G->B(illion), T->T(trillion),.... (by pure luck, this is really just one necessary replacement in the range I've listed).

The reason seems to be that plotly relies on d3-format, which claims to "format numbers for human consumption" but misses the one format non-technically trained humans can actually consume at ease.

However, oddly plotly does use the "human readable" form by default for the X and Y columns in default hover displays, even when they're included in the hover templates manually as %{y}, but not for custom data included via %{customdata[0]} (see the MWE below). This in some sense makes this a bug: You want to include two columns of data in the same way, using the same format specifier, but you get different results.

Instead of waiting on d3, I would like to make this feature request: I believe plotly should default for custom data to the same formatting it uses by default elsewhere (including axes labels), unless a format specifier is explicitly listed, thus increasing consistency.

Example: Despite using text=y and hovertemplate ='%{y}<br>%{text}', I get different representations:

import plotly.graph_objects as go
y = [2, 100000, 2000000, 2000000000]
fig = go.Figure(go.Scatter(
    x = [1,2,3,4],
    y = y,
    text = y,
    hovertemplate ='%{y}<br>%{text}'
))
fig.show()

image

Similar requests elsewhere: https://github.com/plotly/plotly.py/issues/1222

https://stackoverflow.com/questions/68005050/b-billions-instead-of-g-giga-in-python-plotly-customdata-si-prefix-d3

https://stackoverflow.com/questions/17037023/how-to-get-localizable-or-customizable-si-codes-with-d3-format

https://community.plotly.com/t/custom-si-unit-prefixes/29739/4

https://stackoverflow.com/questions/40774677/d3-formatting-tick-value-to-show-b-billion-instead-of-g-giga

https://github.com/d3/d3/issues/2241

https://stackoverflow.com/questions/64313173/how-to-hover-number-formatting-to-k-or-m-accordingly-in-r-plotly-pie-charts-and

https://github.com/d3/d3-format/issues/71

https://github.com/d3/d3-format/pull/81

https://github.com/d3/d3-format/pull/96

pietersv commented 2 years ago

One option is to selectively override d3.format in your application, adding rules your customer base would prefer. The below code overrides d3.format to define a whimsical custom format , and fall back to standard d3.format otherwise

var _d3format = d3.format

d3.format = function(fmt) {
  var getMagnitude = function(v) { return Math.floor(Math.log10(v)/3)}
  var prefixes = ['do','di','re','ri','mi','fa','fi','so','si','la','li','ti','do']
  var getPrefix = function(mag) { return prefixes[mag]}

  if (fmt == 'solfege') {
    return function(val) {
      var str = _d3format('s')(val)
      var mag = getMagnitude(val)          
      if (mag>4 && mag<4+prefixes.length) {
        var base = str.slice(0,3)
        var pre = getPrefix(mag-4)
        return base + ' '+ pre + "zillions"
      } 
      else return _d3format("0.3s")(val)
    } 
  }
  else return _d3format(fmt)
}

e.g. d3.format('solfege')(3403940323489323092394829839240) yields "340 fizillions"

Of course, be careful if your code is to be embedded in other code, where polluting d3 might cause issues with other libraries

gvwilson commented 1 month ago

Hi - we are trying to tidy up the stale issues and PRs in Plotly's public repositories so that we can focus on things that are still important to our community. Since this one has been sitting for several years, I'm going to close it; if it is still a concern, please add a comment letting us know what recent version of our software you've checked it with so that I can reopen it and add it to our backlog. Thanks for your help - @gvwilson

soerenwolfers commented 1 month ago

@gvwilson Still a problem with 5.22