Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Layering mark_rule and mark_text results in text duplication #3774

Open
danhamill opened this issue Jan 17, 2025 · 2 comments
Open

Layering mark_rule and mark_text results in text duplication #3774

danhamill opened this issue Jan 17, 2025 · 2 comments

Comments

@danhamill
Copy link

danhamill commented Jan 17, 2025

What happened?

Related to this SO post. For this example on the documentation page:

import pandas as pd
import altair as alt

source = pd.DataFrame({
    "Day": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15],
    "Value": [55, 112, 65, 38, 80, 138, 120, 103, 395, 200, 72, 51, 112, 175, 131]
})
threshold = 300

bars = alt.Chart(source).mark_bar(color="steelblue").encode(
    x="Day:O",
    y="Value:Q",
)

highlight = bars.mark_bar(color="#e45755").encode(
    y2=alt.Y2(datum=threshold)
).transform_filter(
    alt.datum.Value > threshold
)

rule = alt.Chart().mark_rule().encode(
    y=alt.Y(datum=threshold)
)

label = rule.mark_text(
    x="width",
    dx=-2,
    align="right",
    baseline="bottom",
    text="hazardous"
)

(bars + highlight + rule + label)

The text "hazardous" on the plot looks blurry.

enter image description here

What would you like to happen instead?

I would like the mark_text font/weight to appear the same as the axis labels.

Which version of Altair are you using?

5.5.0

@danhamill danhamill added bug needs-triage Bug report needs maintainer response labels Jan 17, 2025
@hydrosquall
Copy link
Member

hydrosquall commented Jan 20, 2025

From what I can see, the issue is we are somehow drawing 1 rule per row fo data. I used the SVG renderer to see the marks more clearly)

Image

Comparing the simplified example with a fixed version, I found that deleting the data row lets us draw the marks once!

Before - blurry After - delete marks[n].from
Image Image

The rule is getting drawn as many times as the text, but it's less blurry than with the text since the geometry is simpler.

If we check the Vega-Lite gallery equivalent, this example doesn't have the duplicate draws problem

Image

The issue can be resolved by aligning the Altair example with the Vega-Lite example using two nested layers. The first layer handles rectangles, binding to the inline data to draw one mark per row. The second layer binds to the rule and text marks, avoiding repeated drawing. Alternatively, the Vega-Lite example can be simplified to a single layer by inlining a one-row data object for the rule and text marks. See this example where I've made a minimal change to the Altair generated spec.

I'll leave it to the Altair core team to decide on doc updates, but this info should let you avoid unwanted repeat draws in new graphs. In short, marks that should only be drawn once should be bound to single-row datasets. Feel free to reach out in the VL repo if you have feedback on the nesting of layers in the public VL example.

@dangotbanned
Copy link
Member

#3774 (comment)

@hydrosquall Very impressive detective work there! 😉

cc @joelostblom as it seems you directed the Stack Overflow question here

@dangotbanned dangotbanned added documentation and removed needs-triage Bug report needs maintainer response labels Jan 20, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants