Skip to the content

EXECUTED WITH R 4.3.3

This script is run with R 4.3.3, by tools/data-science/run_r_equivalents.py, and the lab page shows what it printed and the plots it drew. Every number in its comments was checked against that output.

The code

Straight from labs/course-6-r/17_plotly.R, unchanged.

# =====================================================================
# Run with R 4.3.3. Rscript builds each chart but has nowhere to show it, so
# _drive_17_plotly.py runs this file with each chart saved as a web page, and
# opens each in Chromium for the screenshots on the lab page. (Until October
# 2026 R could not be installed where these labs are checked, so this file
# was desk-checked only.)
# =====================================================================
# Experiment 17: Interactive visualisations with plotly
# No Python equivalent -- this demonstrates plotly's R interface specifically.

library(plotly); library(ggplot2)

# Step 1: Make the students data frame
students <- data.frame(
  name    = c("Ananya","Bhavana","Charan","Divya","Eshwar",
              "Fiona","Gopal","Harika","Ismail","Jyothi"),
  section = c("A","A","B","B","A","C","C","B","A","C"),
  hours   = c(9, 5, 11, 4, 7, 8, 3, 10, 6, 2),
  marks   = c(85, 62, 91, 55, 74, 79, 48, 88, 68, 41))

# --- THE ONE-LINE ROUTE: convert any ggplot2 plot ---
# Step 2: Make a ggplot2 chart interactive
p <- ggplot(students, aes(x = hours, y = marks, colour = section)) +
       geom_point(size = 3) +
       labs(title = "Marks against study hours")
ggplotly(p)          # hover, zoom and pan now work. That is the whole trick.

# --- NATIVE plotly ---
# Step 3: Draw a native plotly scatter, with hover text
plot_ly(students,
        x = ~hours, y = ~marks, color = ~section,      # NOTE the ~
        type = "scatter", mode = "markers",
        marker = list(size = 12),
        text = ~paste("Name:", name, "<br>Marks:", marks),
        hoverinfo = "text") %>%
  layout(title = "Marks against study hours",
         xaxis = list(title = "Hours studied"),
         yaxis = list(title = "Marks"))

# TWO THINGS THAT CATCH PEOPLE:
#   1. plotly uses FORMULA notation (~hours) to name columns. Writing
#      x = hours looks for a variable in your environment and fails.
#   2. plotly layers chain with %>%, NOT with + . This is the reverse of
#      ggplot2, and mixing them is the commonest plotly error.

# --- BAR AND LINE ---
# Step 4: Draw a bar chart of the means
avg <- aggregate(marks ~ section, students, mean)
plot_ly(avg, x = ~section, y = ~marks, type = "bar",
        marker = list(color = "#1e7fbf"))

# --- ANIMATION: one extra argument ---
# library(gapminder)
# plot_ly(gapminder, x = ~gdpPercap, y = ~lifeExp,
#         size = ~pop, color = ~continent,
#         frame = ~year,                 # <- this creates the animation
#         type = "scatter", mode = "markers") %>%
#   layout(xaxis = list(type = "log")) %>%
#   animation_opts(frame = 1000, transition = 500, redraw = FALSE)
#
# frame = ~year is ALL an animation needs. plotly adds the play button and
# the slider automatically -- the famous Gapminder chart in six lines.

# --- RANGE SLIDER for a time series ---
# plot_ly(x = ~time(AirPassengers), y = ~AirPassengers,
#         type = "scatter", mode = "lines") %>%
#   rangeslider()

# --- EXPORT ---
# htmlwidgets::saveWidget(fig, "plot.html")

Where this sits

This one is R-specific — there is no Python equivalent in this lab.

The theory behind it is in this course’s units; the whole lab, with all 18 experiments, is on the lab page.