Search code examples
pythonjupyter-labaltairvega-litevega

Registering custom vega formatters in jupyterlab with altair


I'm trying to implement a custom formatter formatType that I can use with altair in jupyterlab. I cannot figure out how to register the vega expression function in jupyterlab. It works when using the vega-editor and injecting the expression using the JS console. How to register the expression function from a jupyterlab cell?

Using the definition generated by

import altair as alt
import pandas as pd

def pub_theme():
    return {'config': {"customFormatTypes": True}}
alt.themes.register('pub', pub_theme)
alt.themes.enable('pub')

alt.Chart(
    pd.DataFrame({'x': [1e-3, 1e-2, 1, 1e10], 'y':[1e-3, 1e-2, 1, 1e10]})
).mark_line(
).encode(
    y=alt.Y('y:Q'),
    x=alt.X('x:Q', axis=alt.Axis(formatType='pubformat'))
)

and opening the definition in the Vega-lite editor gives as expected [Error] Unrecognized function: pubformat

If pubformat is defined via the JS console witg e.g. VEGA_DEBUG.vega.expressionFunction('pubformat', function() {return 'test'}), then the editor produces the expected output with 6 identical labels test on the x axis.

What is the correct way to achieve this within jupyterlab?

Injecting the expression vega.expressionFunction('pubformat', function() {return 'test'})from the JS console on the jupyterlab page doesn't work. Defining it via

from IPython.display import HTML
    HTML("""
        <script>
            vega.expressionFunction('pubformat', function() {return 'test'})
        </script>
     """)

didn't work neither.

If injecting javascript is an issue, are there any other options for implementing a custom formatter in altair? It seems that a similar behavior can be achieve using labelExpr on the axis, however this is less generic, as the expression must be repeated for each axis. Thank you!


Solution

  • Custom formatters in Vega-Lite were added in version 4.11; Altair currently supports Vega-Lite v4.8.1, so custom formatters are not supported by the current release of Altair.