简体   繁体   中英

Text above axes of an interactive Altair plot

I have been following the advice on the question here to place various tips/information on my plots in Altair for a little while now. However, this advice does not work if the Altair plot is set to interactive() - it appears to me that enabling the scale binding prevents any plot objects from appearing outside of the rectangular axes.

Here is a reproducing example based on that link: compare the generated plots with/without the commented interactive() line at the end.

    import altair as alt
    import pandas as pd
    import numpy as np

    df = pd.DataFrame({'x': np.linspace(0, 4, 1000)})
    df['y'] = np.sin(2 * np.pi * df['x'])

    select_point = alt.selection_single(fields=('x',), nearest=True, on='mouseover', empty='none')
    line = alt.Chart(df).mark_line().encode(
        x='x:Q',
        y='y:Q',
    )
    points = line.mark_point(filled=True, size=100).encode(
        opacity=alt.condition(select_point, alt.value(1.0), alt.value(0.0)),
    ).add_selection(select_point)
    text1 = alt.Chart(df, width=600, height=400).mark_text(
        align='left', baseline='bottom', dx=+5, fontSize=12,
    ).encode(
        x=alt.value(0.0),
        y=alt.value(-1),
        text='_label:N',
        opacity=alt.condition(select_point, alt.value(1.0), alt.value(0.0)),
    ).transform_calculate(
        _label='"ABOVE AXES x = " + format(datum.x, ".2f") + ", y = " + format(datum.y, ".2f")',
    )
    text2 = alt.Chart(df, width=600, height=400).mark_text(
        align='left', baseline='bottom', dx=+5, fontSize=12,
    ).encode(
        x=alt.value(0.0),
        y=alt.value(12),
        text='_label:N',
        opacity=alt.condition(select_point, alt.value(1.0), alt.value(0.0)),
    ).transform_calculate(
        _label='"INSIDE AXES x = " + format(datum.x, ".2f") + ", y = " + format(datum.y, ".2f")',
    )
    chart = alt.layer(line, points, text1, text2)
    # chart = chart.interactive()

Interactive OFF Interactive ON

Additional information, in case it is helpful/relevant:

  • I tested this with both interactive() and manual selection scale binding, with the same effect
  • I am rendering in a PyQT WebEngineView container after saving the chart as HTML
  • There is definitely some sort of tracking of objects beyond the axes boundary, even when they are not shown with interactive ON. I have also tested with point markers: large markers that hang over the edge of the axes boundary are fully visible with interactive OFF but cut off with interactive ON. However, if you have interactive ON and slowly drag the axis boundaries, you can see the plot title shift upwards to avoid a large marker sliding off the top edge of the plot, right up until the center of the marker leaves the boundary and the title snaps back down.

Bottom line question: how can I get text to appear outside of the axes boundaries in Altair when the plot is set to be interactive?

Pass clip=False to mark_text() , and text will be visible outside the axis.

The clip parameter default to False for non-bound scales, and True for bound scales.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM