Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to set locale in Altair?

Tags:

python

altair

I'm successfully creating and rendering a chart in Altair with a currency prefix ($), but I need this to be set to GBP (£). I know that there's a Vega-lite formatLocale which can be set, but I can't work out how to pass the value I need to Vega-lite. I can't find anything on locale in the Altair docs.

   def chart_tenders_monthly_value(dataframe=None):
        chart = (
            alt.Chart(dataframe, title="Tender value")
                .mark_bar()
                .encode(
                alt.X(
                    "yearmonth(date):O",
                     axis=alt.Axis(title="Month") 
                     ),
                alt.Y("total_monthly_value:Q",
                     axis=alt.Axis(title="Monthly cumulative tender value (£)") 
                     ),
                tooltip=[
                    alt.Tooltip('total_monthly_value:Q', title="Total value", format="$,.4r"), 
                    alt.Tooltip('median_monthly_value:Q', title="Median value", format="$,.4r"),
                    alt.Tooltip('no_of_tenders:Q', title="Total tenders", format=",.2r")
                ],
                color = 'variable:N'
            )
        )

        text = (
            chart.mark_text(align="center", baseline="bottom")
            .encode(text='label:N')
            .transform_calculate(label=f'format(datum.total_monthly_value,"$,.3s")')
        )
        return chart+text

screenshot of rendered chart

like image 259
woodbine Avatar asked Sep 19 '19 15:09

woodbine


1 Answers

In Altair 4.0 or newer, you can set format locales and time format locales via the renderer embed options. The locales are set via JSON objects that compactly specify how values should be displayed.

  • formatLocale options, which define formats for currency and numbers, can be found here: https://github.com/d3/d3-format/tree/main/locale

  • timeFormatLocale options, which define formats for times and dates, can be found here: https://github.com/d3/d3-time-format/tree/main/locale

Here is an example of setting the renderer to use German (DE) time and currency formats:

import altair as alt
import pandas as pd
from urllib import request
import json

# fetch & enable a German format & timeFormat locales.
with request.urlopen('https://raw.githubusercontent.com/d3/d3-format/master/locale/de-DE.json') as f:
  de_format = json.load(f)
with request.urlopen('https://raw.githubusercontent.com/d3/d3-time-format/master/locale/de-DE.json') as f:
  de_time_format = json.load(f)
alt.renderers.set_embed_options(formatLocale=de_format, timeFormatLocale=de_time_format)

df = pd.DataFrame({
    'date': pd.date_range('2020-01-01', freq='M', periods=6),
    'revenue': [100000, 110000, 90000, 120000, 85000, 115000]
})

alt.Chart(df).mark_bar().encode(
    y='month(date):O',
    x=alt.X('revenue:Q', axis=alt.Axis(format='$,r'))
)

enter image description here


Original Answer:

It's possible, but unfortunately not well supported. formatLocale() is a javascript function that must be called by the renderer. The Javascript code used by Jupyter Notebook and JupyterLab is hard-coded within their respective vega extensions, so there is no way to change this for Altair charts visualized in those frontends.

If you want to adjust the locale yourself, the easiest way would be to export the chart to HTML (chart.save('mychart.html')) then add a call to formatLocale in the javascript within the HTML output.

If you want to do this in a more automatic/repeatable, you could modify Altair's html output template (source) and create your own exporter function that converts a chart to HTML with locale settings or other custom javascript.

like image 96
jakevdp Avatar answered Nov 07 '22 09:11

jakevdp