knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>"
)

This document is adapted from the Bar Charts section of the Altair Example Gallery.

Our first step is to set up our environment:

library("altair")
library("tibble")
library("jsonlite")

vega_data <- import_vega_data()

Bar Chart with Highlighted Bar

Altair example

Data

glimpse(vega_data$wheat())

Chart

chart <- 
  alt$Chart(vega_data$wheat())$
  mark_bar()$
  encode(
    x = "year:O",
    y = "wheat:Q",
    # The highlight will be set on the result of a conditional statement
    color=alt$condition(
      "datum.year == 1810",  # If the year is 1810 this test returns True,
      alt$value("orange"),     # which sets the bar orange.
      alt$value("steelblue")   # If it's not True, it sets the bar steelblue.
    )
  )$properties(width=600)

chart

Bar Chart with Labels

Altair example

Data

glimpse(vega_data$wheat())

Chart

bars <- 
  alt$Chart(vega_data$wheat())$
  mark_bar()$
  encode(
    x = "wheat:Q",
    y = "year:O"
  )

text <- 
  bars$
  mark_text(align = "left", baseline = "middle", dx = 3)$
  encode(
    text = "wheat:Q"
  )

chart <- (bars + text)$properties(height = 800)

chart

Bar Chart with Line as Mean

Altair example

Data

glimpse(vega_data$wheat())

Chart

source <- vega_data$wheat()

bar <- 
  alt$Chart(source)$
  mark_bar()$
  encode(
    x = "year:O",
    y = "wheat:Q"
  )

rule <- 
  alt$Chart(source)$
  mark_rule(color = "red")$
  encode(
    y = "mean(wheat):Q"
  )

chart <- (bar + rule)$properties(width = 600)

chart

Bar Chart with Line on Dual Axis

Altair example

This seems exemplary of why dual-axes should be used with caution.

Data

glimpse(vega_data$wheat())

Chart

base <- 
  alt$Chart(vega_data$wheat())$
  encode(
    x = "year:O"
  )

bar <- 
  base$
  mark_bar()$
  encode(
    y = "wheat:Q"
  )


line <-  
  base$
  mark_line(color = "red")$
  encode(
    y = "wages:Q"
  )

chart <-
  (bar + line)$
  properties(width = 600)

chart

Bar Chart with Negative Values

Altair example

Data

glimpse(vega_data$us_employment())

Chart

chart <- 
  alt$Chart(vega_data$us_employment())$
  mark_bar()$
  encode(
    x = "month:T",
    y = "nonfarm_change:Q",
    color = alt$condition(
      "datum.nonfarm_change > 0",  
      alt$value("steelblue"), # positive color
      alt$value("orange")     # negative color
    )
  )$properties(width = 600)

chart

Bar and Tick Chart

Altair example

Data

Definition

data <- 
  tibble(
    project = c("a", "b", "c", "d", "e", "f", "g"),
    score = c(25, 57, 23, 19, 8, 47, 8),
    goal = c(25, 47, 30, 27, 38, 19, 4)
  )

glimpse(data)

Chart

bar <- 
  alt$Chart(data = data)$
  mark_bar()$
  encode(
    x = "project:O",
    y = "score:Q"
  )$
  properties(width = alt$Step(40))

tick <- 
  alt$Chart(data = data)$
  mark_tick(
    color = "red",
    thickness = 2,
    size = 40 * 0.9
  )$
  encode(
    x = "project:O",
    y = "goal:Q"
  )

chart <- (bar + tick)

chart

Calculating Percentage of Total

Altair example

In the Altair example, we see some code like this:

alt.WindowFieldDef(op='sum', field='Time', **{'as': 'TotalTime'})

In R, supply the stuff inside the **{} as additional arguments to the function:

alt$WindowFieldDef(op = "sum", field = "Time", as = "TotalTime")

See the Field Guide to Python Issues for more details and more examples.

Data

Definition

activities <- 
  tibble(
    Activity = c("Sleeping", "Eating", "TV", "Work", "Exercise"),
    Time = c(8, 2, 4, 8, 2)
  )

glimpse(activities)

Chart

chart <- 
  alt$Chart(activities)$
  transform_joinaggregate(
    TotalTime = "sum(Time)"
  )$
  transform_calculate(PercentOfTotal = "datum.Time / datum.TotalTime")$
  mark_bar()$
  encode(
    alt$X("PercentOfTotal:Q", axis = alt$Axis(format = ".0%")),
    y = "Activity:N"
  )

chart

Diverging Stacked Bar Chart

Altair example

This example shows a diverging stacked bar chart for sentiments towards a set of eight questions, displayed as percentages with neutral responses straddling the 0% mark.

Data

Definition

data <- fromJSON('[
  {
    "question": "Question 1",
    "type": "Strongly disagree",
    "value": 24,
    "percentage": 0.7,
    "percentage_start": -19.1,
    "percentage_end": -18.4
  },
  {
    "question": "Question 1",
    "type": "Disagree",
    "value": 294,
    "percentage": 9.1,
    "percentage_start": -18.4,
    "percentage_end": -9.2
  },
  {
    "question": "Question 1",
    "type": "Neither agree nor disagree",
    "value": 594,
    "percentage": 18.5,
    "percentage_start": -9.2,
    "percentage_end": 9.2
  },
  {
    "question": "Question 1",
    "type": "Agree",
    "value": 1927,
    "percentage": 59.9,
    "percentage_start": 9.2,
    "percentage_end": 69.2
  },
  {
    "question": "Question 1",
    "type": "Strongly agree",
    "value": 376,
    "percentage": 11.7,
    "percentage_start": 69.2,
    "percentage_end": 80.9
  },

  {
    "question": "Question 2",
    "type": "Strongly disagree",
    "value": 2,
    "percentage": 18.2,
    "percentage_start": -36.4,
    "percentage_end": -18.2
  },
  {
    "question": "Question 2",
    "type": "Disagree",
    "value": 2,
    "percentage": 18.2,
    "percentage_start": -18.2,
    "percentage_end": 0
  },
  {
    "question": "Question 2",
    "type": "Neither agree nor disagree",
    "value": 0,
    "percentage": 0,
    "percentage_start": 0,
    "percentage_end": 0
  },
  {
    "question": "Question 2",
    "type": "Agree",
    "value": 7,
    "percentage": 63.6,
    "percentage_start": 0,
    "percentage_end": 63.6
  },
  {
    "question": "Question 2",
    "type": "Strongly agree",
    "value": 11,
    "percentage": 0,
    "percentage_start": 63.6,
    "percentage_end": 63.6
  },

  {
    "question": "Question 3",
    "type": "Strongly disagree",
    "value": 2,
    "percentage": 20,
    "percentage_start": -30,
    "percentage_end": -10
  },
  {
    "question": "Question 3",
    "type": "Disagree",
    "value": 0,
    "percentage": 0,
    "percentage_start": -10,
    "percentage_end": -10
  },
  {
    "question": "Question 3",
    "type": "Neither agree nor disagree",
    "value": 2,
    "percentage": 20,
    "percentage_start": -10,
    "percentage_end": 10
  },
  {
    "question": "Question 3",
    "type": "Agree",
    "value": 4,
    "percentage": 40,
    "percentage_start": 10,
    "percentage_end": 50
  },
  {
    "question": "Question 3",
    "type": "Strongly agree",
    "value": 2,
    "percentage": 20,
    "percentage_start": 50,
    "percentage_end": 70
  },

  {
    "question": "Question 4",
    "type": "Strongly disagree",
    "value": 0,
    "percentage": 0,
    "percentage_start": -15.6,
    "percentage_end": -15.6
  },
  {
    "question": "Question 4",
    "type": "Disagree",
    "value": 2,
    "percentage": 12.5,
    "percentage_start": -15.6,
    "percentage_end": -3.1
  },
  {
    "question": "Question 4",
    "type": "Neither agree nor disagree",
    "value": 1,
    "percentage": 6.3,
    "percentage_start": -3.1,
    "percentage_end": 3.1
  },
  {
    "question": "Question 4",
    "type": "Agree",
    "value": 7,
    "percentage": 43.8,
    "percentage_start": 3.1,
    "percentage_end": 46.9
  },
  {
    "question": "Question 4",
    "type": "Strongly agree",
    "value": 6,
    "percentage": 37.5,
    "percentage_start": 46.9,
    "percentage_end": 84.4
  },

  {
    "question": "Question 5",
    "type": "Strongly disagree",
    "value": 0,
    "percentage": 0,
    "percentage_start": -10.4,
    "percentage_end": -10.4
  },
  {
    "question": "Question 5",
    "type": "Disagree",
    "value": 1,
    "percentage": 4.2,
    "percentage_start": -10.4,
    "percentage_end": -6.3
  },
  {
    "question": "Question 5",
    "type": "Neither agree nor disagree",
    "value": 3,
    "percentage": 12.5,
    "percentage_start": -6.3,
    "percentage_end": 6.3
  },
  {
    "question": "Question 5",
    "type": "Agree",
    "value": 16,
    "percentage": 66.7,
    "percentage_start": 6.3,
    "percentage_end": 72.9
  },
  {
    "question": "Question 5",
    "type": "Strongly agree",
    "value": 4,
    "percentage": 16.7,
    "percentage_start": 72.9,
    "percentage_end": 89.6
  },

  {
    "question": "Question 6",
    "type": "Strongly disagree",
    "value": 1,
    "percentage": 6.3,
    "percentage_start": -18.8,
    "percentage_end": -12.5
  },
  {
    "question": "Question 6",
    "type": "Disagree",
    "value": 1,
    "percentage": 6.3,
    "percentage_start": -12.5,
    "percentage_end": -6.3
  },
  {
    "question": "Question 6",
    "type": "Neither agree nor disagree",
    "value": 2,
    "percentage": 12.5,
    "percentage_start": -6.3,
    "percentage_end": 6.3
  },
  {
    "question": "Question 6",
    "type": "Agree",
    "value": 9,
    "percentage": 56.3,
    "percentage_start": 6.3,
    "percentage_end": 62.5
  },
  {
    "question": "Question 6",
    "type": "Strongly agree",
    "value": 3,
    "percentage": 18.8,
    "percentage_start": 62.5,
    "percentage_end": 81.3
  },

  {
    "question": "Question 7",
    "type": "Strongly disagree",
    "value": 0,
    "percentage": 0,
    "percentage_start": -10,
    "percentage_end": -10
  },
  {
    "question": "Question 7",
    "type": "Disagree",
    "value": 0,
    "percentage": 0,
    "percentage_start": -10,
    "percentage_end": -10
  },
  {
    "question": "Question 7",
    "type": "Neither agree nor disagree",
    "value": 1,
    "percentage": 20,
    "percentage_start": -10,
    "percentage_end": 10
  },
  {
    "question": "Question 7",
    "type": "Agree",
    "value": 4,
    "percentage": 80,
    "percentage_start": 10,
    "percentage_end": 90
  },
  {
    "question": "Question 7",
    "type": "Strongly agree",
    "value": 0,
    "percentage": 0,
    "percentage_start": 90,
    "percentage_end": 90
  },

  {
    "question": "Question 8",
    "type": "Strongly disagree",
    "value": 0,
    "percentage": 0,
    "percentage_start": 0,
    "percentage_end": 0
  },
  {
    "question": "Question 8",
    "type": "Disagree",
    "value": 0,
    "percentage": 0,
    "percentage_start": 0,
    "percentage_end": 0
  },
  {
    "question": "Question 8",
    "type": "Neither agree nor disagree",
    "value": 0,
    "percentage": 0,
    "percentage_start": 0,
    "percentage_end": 0
  },
  {
    "question": "Question 8",
    "type": "Agree",
    "value": 0,
    "percentage": 0,
    "percentage_start": 0,
    "percentage_end": 0
  },
  {
    "question": "Question 8",
    "type": "Strongly agree",
    "value": 2,
    "percentage": 100,
    "percentage_start": 0,
    "percentage_end": 100
  }
]')

glimpse(data)

Chart

color_scale <-
  alt$Scale(
    domain = list(
      "Strongly disagree",
      "Disagree",
      "Neither agree nor disagree",
      "Agree",
      "Strongly agree"
    ),
    range = list("#c30d24", "#f3a583", "#cccccc", "#94c6da", "#1770ab")
  )

y_axis <-
  alt$Axis(
    title = "Question",
    offset = 5,
    ticks = FALSE,
    minExtent = 60,
    domain = FALSE
  )

chart <- 
  alt$Chart(data)$
  mark_bar()$
  encode(
    x = "percentage_start:Q",
    x2 = "percentage_end:Q",
    y = alt$Y("question:N", axis = y_axis),
    color = alt$Color(
      "type:N",
      legend = alt$Legend(title = "Response"),
      scale = color_scale
    )
  )

chart

Grouped Bar Chart

Altair example

Data

source <- vega_data$barley()

glimpse(source)

Chart

chart <- 
  alt$Chart(vega_data$barley())$
  mark_bar()$
  encode(
    x = "year:O",
    y = "sum(yield):Q",
    color = "year:N",
    column = "site:N"
  )

chart

Grouped Bar Chart with Error Bars

Altair example

This example shows how to show error bars using confidence intervals. The confidence intervals are computed internally in vega by a non-parametric bootstrap of the mean.

Data

source <- vega_data$barley()

glimpse(source)

Chart

bars <- 
  alt$Chart()$
  mark_bar()$
  encode(
    x = "year:O",
    y = alt$Y(
      "mean(yield):Q",
      axis = alt$Axis(title = "Mean Yield")
    ),
    color = "year:N"
  )

error_bars <- 
  alt$Chart()$
  mark_errorbar(extent = "ci")$
  encode(
    x = "year:O",
    y = "yield:Q"
  )

chart <- 
  alt$layer(bars, error_bars, data = source)$
  facet(
    column = "site:N"
  )


chart

Horizontal Bar Chart

Altair example

Note that the argument to the transform_filter() function is a JavaScript expression that refers to a variable in the data using the datum. prefix.

Data

glimpse(vega_data$wheat())

Chart

chart <- 
  alt$Chart(vega_data$wheat())$
  mark_bar()$
  encode(
    x = "wheat:Q",
    y = "year:O"
  )$
  properties(height = 700)

chart

Horizontal Grouped Bar Chart

Altair example

Data

glimpse(vega_data$barley())

Chart

chart <- 
  alt$Chart(vega_data$barley())$
  mark_bar()$
  encode(
    x = "sum(yield):Q",
    y = "year:O",
    color = "year:N",
    row = "site:N"
  )

chart

Horizontal Stacked Bar Chart

Altair example

Data

glimpse(vega_data$barley())

Chart

chart <- 
  alt$Chart(vega_data$barley())$
  mark_bar()$
  encode(
    x = "sum(yield)",
    y = "variety",
    color = "site"
  )

chart

Layered Bar Chart

Altair example

Data

glimpse(vega_data$iowa_electricity())

Chart

chart <- 
  alt$Chart(vega_data$iowa_electricity())$
  mark_bar(opacity = 0.7)$
  encode(
    x = "year:O",
    y = alt$Y("net_generation:Q", stack = NULL),
    color = "source"
  )

chart

Normalized Stacked Bar Chart

Altair example

Data

glimpse(vega_data$barley())

Chart

chart <- 
  alt$Chart(vega_data$barley())$
  mark_bar()$
  encode(
    x = alt$X("sum(yield)", stack = "normalize"),
    y = "variety",
    color = "site"
  )

chart

Sorted Bar Chart

Altair example

glimpse(vega_data$barley())

Chart

chart <- 
  alt$Chart(vega_data$barley())$
  mark_bar()$
  encode(
    x = "sum(yield):Q",
    y = alt$Y(
      "site:N",
      sort = alt$EncodingSortField(
        field = "yield",     # field to use for the sort
        op = "sum",          # operation to run on the field prior to sorting
        order = "descending" # order to sort in
      )
    )
  )

chart

Stacked Bar Chart

Altair example

glimpse(vega_data$barley())

Chart

chart <- 
  alt$Chart(vega_data$barley())$
  mark_bar()$
  encode(
    x = "variety",
    y = "sum(yield)",
    color = "site"
  )

chart

Stacked Bar Chart with Sorted Segments

Altair example

glimpse(vega_data$barley())

Chart

chart <- 
  alt$Chart(vega_data$barley())$
  mark_bar()$
  encode(
    y = "variety",
    x = "sum(yield)",
    color = "site",
    order = alt$Order(
      # Sort the segments of the bars by this field
      "site",
      sort ="ascending"
    )
  )

chart

Stacked Bar Chart with Text Overlay

Altair example

glimpse(vega_data$barley())

Chart

source <- vega_data$barley()

bars <- 
  alt$Chart(source)$
  mark_bar()$
  encode(
    x = alt$X("sum(yield):Q", stack = "zero"),
    y = "variety:N",
    color ="site:N"
  )

text = alt$Chart(source)$
  mark_text(dx = -15, dy = 3, color = "white")$
  encode(
    x =alt$X("sum(yield):Q", stack = "zero"),
    y = "variety:N",
    detail = "site:N",
    text=alt$Text("sum(yield):Q", format = ".1f")
  )

chart <- (bars + text)

chart

Trellis Stacked Bar Chart

Altair example

glimpse(vega_data$barley())

Chart

chart <- 
  alt$Chart(vega_data$barley())$
  mark_bar()$
  encode(
    x = "yield",
    y = "variety",
    color = "site",
    column = "year"
  )$
  properties(width = 220)

chart


vegawidget/altair documentation built on Feb. 3, 2024, 7:47 p.m.