I was trying to write a table with some entries being multi-line using altair, but seem to get into trouble with fixing line spacing. For example:
text_df = pd.DataFrame({"a":["very very very very long thing", "very very very very very long thing"]})
text_chart_base = alt.Chart(text_df).transform_window(row_number="row_number()").transform_calculate(
y=f"split(datum.a, ' ')"
).mark_text(align="left", baseline="top"
).encode(y=alt.Y("row_number:N", axis=None, scale=alt.Scale(reverse=True)))
col1 = text_chart_base.encode(text=f"y:N")
col2= text_chart_base.encode(text=f"row_number:N")
col1 | col2
gives me overlapping multi-line strings
Instead when I make the row_number
Quantitative with encode(y=alt.Y("row_number:Q", axis=None, scale=alt.Scale(reverse=True)))
, I get too much space between the strings
Is there a way I can get mark_text
to give the right row spacing between rows? (That is, an output something like the following)
You can set the overall height of the chart or the height per tick/step, e.g.:
import altair as alt
import pandas as pd
text_df = pd.DataFrame({"a":["one two three four", "A B", "1 2"]})
text_chart_base = alt.Chart(text_df, height=alt.Step(60)).transform_window(
row_number="row_number()"
).transform_calculate(
y="split(datum.a, ' ')",
).mark_text(
align="left",
baseline="bottom"
).encode(
y=alt.Y("row_number:O")
)
col1 = text_chart_base.encode(text="y:N")
col2 = text_chart_base.encode(text="row_number:N")
col1 | col2
As you can see the spacing is not adaptive to the content but static per position, so there will be a gap between the second on third row. I think it should be possible to fix this by setting the step height to be applied per offset instead of per tick position, but I couldn't get something like this to work:
text_df = pd.DataFrame({"a":["one two three four", "A B", "1 2"]})
text_chart_base = alt.Chart(text_df, height=alt.Step(70, **{'for': 'offset'})).transform_window(
row_number="row_number()"
).transform_calculate(
y="split(datum.a, ' ')",
offset="length(datum.y)"
).mark_text(
align="left",
baseline="bottom"
).encode(
y=alt.Y("row_number:O"),
yOffset=alt.Y("offset:Q")
)
col1 = text_chart_base.encode(text="y:N")
col2 = text_chart_base.encode(text="offset:N")
col1 | col2