7

I am following this example to create a bar chart with conditional color formatting on negative values:

import altair as alt
from vega_datasets import data

source = data.us_employment()

alt.Chart(source).mark_bar().encode(
  x="month:T",
  y="nonfarm_change:Q",
  color=alt.condition(
      alt.datum.nonfarm_change > 0,
      alt.value("steelblue"),  # The positive color
      alt.value("orange")  # The negative color
  )
 ).properties(width=600)

How can I replace alt.datum.nonfarm_change with an expression accepting a dynamic variable name e.g. different columns of a dataframe?

AleAve81
  • 275
  • 3
  • 8
  • It's unclear what you are asking. What do you mean by a "dynamic variable name"? Can you give an example? – jakevdp Dec 20 '19 at 16:56
  • I mean that I want to be able to pass the name of the variable as a parameter as opposed to hardcoding it. Imagine my plot is embedded in a function that returns the plot JSON representation and the function accepts a variable as input argument. Let's say the variable is called var and , how do I do alt.datum.var ? – AleAve81 Dec 21 '19 at 13:46

1 Answers1

11

Python provides a getattr function that lets you get a dynamic attribute from any Python object, so you could use getattr(alt.datum, col_name) to get a dynamic column name from the alt.datum object.

But it's probably easier to specify your filter condition as a string directly; something like this (which makes use of f-strings):

import altair as alt
from vega_datasets import data

def plot_column(col_name: str) -> alt.Chart:
    source = data.us_employment()

    return alt.Chart(source).mark_bar().encode(
      x="month:T",
      y=f"{col_name}:Q",
      color=alt.condition(
          f"datum.{col_name} > 0",
          alt.value("steelblue"),  # The positive color
          alt.value("orange")  # The negative color
      )
    ).properties(width=600)

plot_column("nonfarm_change")

enter image description here

jakevdp
  • 77,104
  • 11
  • 125
  • 160
  • 1
    now what if the column name has a space? "Profit Loss". i am trying alt.datum.["Profit Loss"] > 0 or alt.datum.str("Profit Loss") ... how can i use a column name in a condition that has spaces in its name? thanks – jon rios Nov 24 '20 at 02:47
  • 3
    Use bracket notation: `alt.datum['Profit Loss']` – jakevdp Nov 24 '20 at 04:16
  • Is it possible to plot the legend of the color specified in the alt.Condition() routine. In this example that element with a value <=0 as orange and the rest blue – Andrea Lombardo May 24 '21 at 19:05
  • Hi @jakevdp I am searching for a way of opacity options for a value's conditional status. If the value is smaller than 5, the text will not be visible or its opacity is 0. Is there any option or code in mark_text().encode() section for I need? Thank you. – volkan Feb 04 '23 at 09:39