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

docs: bar chart with labels coloured by measured luminance #3614

Merged
merged 2 commits into from
Sep 27, 2024

Conversation

mattijn
Copy link
Contributor

@mattijn mattijn commented Sep 26, 2024

This PR adds an example that demonstrates how to change the color of text labels based on measured luminance.

The example looks as such:

image

Usage of luminance for the text color of the labels was created using the following code (method-based syntax):

import altair as alt
from vega_datasets import data

source = data.barley()

base = alt.Chart(source).encode(
    x=alt.X('sum(yield):Q').stack('zero'),
    y=alt.Y('site:O').sort('-x'),
    text=alt.Text('sum(yield):Q', format='.0f')
)

bars = base.mark_bar(
    tooltip=alt.expr("luminance(scale('color', datum.sum_yield))")
).encode(
    color='sum(yield):Q'
)

text = base.mark_text(
    align='right',
    dx=-3,
    color=alt.expr("luminance(scale('color', datum.sum_yield)) > 0.5 ? 'black' : 'white'")
)

bars + text

Especially this line

color=alt.expr("luminance(scale('color', datum.sum_yield)) > 0.5 ? 'black' : 'white'")
  • The lighter the bar, the higher the luminance. If the bar is light we like the text overlay be black.
  • The darker the bar, the lower the luminance. If the bar is dark, we like the text overlay be white.

In the expression above this is written as a predicate. The text appears black if the luminance is above 0.5 and white when the luminance is below 0.5. The luminance is computed using the color scale in combination with the internal computed data field datum.sum_yield. Inspecting the luminance can be done through the tooltip by hovering the bars.

Currently this expression is a str with plain Vega Expression syntax. It would be nice to use the equivalent python syntax instead.

@dangotbanned dangotbanned self-assigned this Sep 26, 2024
@joelostblom
Copy link
Contributor

Love this example! I have been doing similar things with a manual threshold as I didn't know there was a function in Vega to compute the luminance already!

Copy link
Member

@dangotbanned dangotbanned left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mattijn I'm truly impressed by how quickly you identified a new example, and this looks great 🎉.

However, this example has identified a bug with the python wrappers, and while it can be worked around - it wouldn't be good content for an example.

Therefore, I'm approving your solution but would ask if you could please open a new issue so that we can track a fix?

Current non str version

import altair as alt
from vega_datasets import data

source = data.barley()

base = alt.Chart(source).encode(
    x=alt.X("sum(yield):Q").stack("zero"),
    y=alt.Y("site:O").sort("-x"),
    text=alt.Text("sum(yield):Q", format=".0f"),
)

# NOTE: Original `str` expressions
# tooltip = alt.expr("luminance(scale('color', datum.sum_yield))")
# color = alt.expr("luminance(scale('color', datum.sum_yield)) > 0.5 ? 'black' : 'white'")

luminance = alt.expr.luminance(alt.expr.scale("color", alt.datum.sum_yield))

# BUG: These definitions alone *should* work, but don't evaluate as expressions
tooltip = luminance
color = alt.expr.if_(luminance > 0.5, "black", "white")

# HACK: Actual additional steps required
tooltip = alt.expr(repr(luminance))
color = alt.expr(repr(color))

bars = base.mark_bar(tooltip=tooltip).encode(color="sum(yield):Q")
text = base.mark_text(align="right", dx=-3, color=color)

bars + text

Sadly #3600 won't resolve this issue, but this did help me identify a different regression on that branch - very grateful for that thank you

@dangotbanned dangotbanned removed their assignment Sep 27, 2024
@mattijn mattijn merged commit cabf1e6 into main Sep 27, 2024
25 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants