vega / altair

Declarative statistical visualization library for Python
https://altair-viz.github.io/
BSD 3-Clause "New" or "Revised" License
9.27k stars 793 forks source link

Adding `tooltip=` changes bar plot #3635

Open MarcoGorelli opened 4 days ago

MarcoGorelli commented 4 days ago

What happened?

import polars as pl
import altair as alt
import numpy as np

rng = np.random.default_rng(1)

df =pl.DataFrame({
"value": rng.normal(0,1,1000)
})

Then, the following two plots differ:

alt.Chart(df).mark_bar().encode(x=alt.X('value', bin=alt.BinParams(step=1)), y='count()', tooltip=['value'])
alt.Chart(df).mark_bar().encode(x=alt.X('value', bin=alt.BinParams(step=1)), y='count()')

Image

What would you like to happen instead?

I think I would expect that adding tooltip= would only affect the interactive behaviour, not what gets displayed

Which version of Altair are you using?

5.4.1

dangotbanned commented 3 days ago

@MarcoGorelli I've put this together for you to play around with

import numpy as np
import polars as pl

import altair as alt

rng = np.random.default_rng(1)
df = pl.DataFrame({"value": rng.normal(0, 1, 1000)})

# Shows all fields
tooltip_bar = True
# Only just discovered this option.
# Highlights that `"value"` isn't in scope
tooltip_bar = {"content": "data"}
# Default
tooltip_bar = alt.Undefined

tooltip_encoding = "count()"
tooltip_encoding = alt.Tooltip("value", bin=alt.Bin(step=1))
# Seems to be the one you want
tooltip_encoding = alt.Tooltip("value", bin=True)
# Default
# tooltip_encoding = alt.Undefined

# These are the same
x = alt.X("value", bin=alt.BinParams(step=1))
x = alt.X("value", bin=alt.Bin(step=1))

base = alt.Chart(df).mark_bar(tooltip=tooltip_bar)
chart = base.encode(x=x, y="count()", tooltip=tooltip_encoding)

chart

Most of these were new to me 😅, but I think this was what you were expecting to see

Image

Related

dangotbanned commented 3 days ago

Just seen this is from https://github.com/pola-rs/polars/issues/19159

I think it might be safer to make this change:

Current

_add_tooltip(encodings, **kwargs)
self._chart.mark_...().encode(**encodings, **kwargs).interactive()

Proposed

self._chart.mark_...(tooltip=True).encode(**encodings, **kwargs).interactive()

The .mark_...() version has a lower precedence than .encode(); so you may be able to avoid L33-L45 entirely.

I'll continue this over there