Steps with Plotly in R

Interactive Data Visualization with plotly

Welcome! ๐ŸŽจ

Note

Interactive Plotting with Plotly

Learn to create beautiful, interactive visualizations in R

What Youโ€™ll Learn:

  • Installing and setting up Plotly
  • Creating interactive scatter plots, box plots, and histograms
  • Understanding binwidths and their impact
  • Customizing interactive plots
  • Building publication-ready visualizations

Part 0: Cool Features of Plotting

Grassy Area Chart Art ๐ŸŒฑ

# ref: https://www.r-graph-gallery.com/138-green-world-data-art/

library(ggplot2)
library(RColorBrewer)
ngroup=20
names=paste("G_",seq(1,ngroup),sep="")
DAT=data.frame()

for(i in seq(1:50)){
  data=data.frame( matrix(0, ngroup , 3))
  data[,1]=i
  data[,2]=sample(names, nrow(data))
  data[,3]=prop.table(sample(
    c(rep(0,100),
    c(1:ngroup)),
    nrow(data)))
  DAT=rbind(DAT,data)
}
colnames(DAT)=c("Year","Group","Value")
DAT=DAT[order( DAT$Year, DAT$Group) , ]

ggplot(DAT, aes(x=Year, y=Value, fill=Group )) + 
  geom_area(alpha=1 , color="transparent" )+
  theme_bw() +
  scale_fill_brewer(palette="greens", breaks=rev(levels(DAT$Group)))+
  theme(line = element_blank(),
        text = element_blank(),
       # line = element_blank(),
        title = element_blank(),
        legend.position="none",
        panel.border = element_blank(),
        panel.background = element_blank())

Tip

Read more about it at Data to Art

Grassy Area Chart Art Output ๐ŸŒฑ

Part 1: Getting Started With Plotly

What is Plotly? ๐Ÿš€

Plotly is a powerful graphing library that creates interactive, publication-quality visualizations

Key Features:

  • Interactive: Hover for details, zoom, pan, download
  • Web-based and shareable: Works in RStudio, R Markdown, and Shiny
  • Versatile: 40+ chart types
  • Beautiful: Professional styling out-of-the-box

Plotly vs ggplot2: ggplot2 excels at static graphics; Plotly adds interactivity for web dashboards and exploration.

Clean Session Setup ๐Ÿงน

Tip

Start with a clean workspace for reproducible R scripts

# Clear objects, plots, and console
remove_existing_objects <- function() {
  rm(list = ls())
  graphics.off()
  cat("\014")
}

remove_existing_objects()

Install and Load Packages ๐Ÿ“ฆ

Note

List the packages your script needs, then install any that are missing.

required_packages <- c('plotly', 'dplyr', 'tidyverse')

install_and_load <- function(packages) {
  for(pkg in packages) {
    if(!require(pkg, character.only = TRUE, quietly = TRUE)) {
      install.packages(pkg)
      library(pkg, character.only = TRUE)
    }
  }
}

install_and_load(required_packages)

Your First Plotly Plot ๐ŸŽฏ

Note

Simple Scatter Plot โ€” The easiest way to start with Plotly

library(plotly)

# Create a simple scatter plot
plot_ly(data = mtcars, 
        x = ~wt, 
        y = ~mpg, 
        type = 'scatter',
        mode = 'markers')

Result: Your First Plot ๐ŸŽฏ

Note

Static ggplot2 version of the plotly output; run the plotly code for the interactive version.

Plotly Syntax: Key Components ๐ŸŽฏ

Note

The first example uses the same core arguments in plot_ly().

  • plot_ly(): Main plotting function
  • data: Your data frame
  • x, y: Variables (use ~ notation)
  • type: Chart type (โ€˜scatterโ€™, โ€˜barโ€™, โ€˜boxโ€™, etc.)
  • mode: For scatter plots (โ€˜markersโ€™, โ€˜linesโ€™, โ€˜markers+linesโ€™)

Interactive Features ๐Ÿ–ฑ๏ธ

Tip

Every Plotly plot comes with built-in interactivity!

Explore the plot:

  1. Hover to inspect data values
  2. Zoom by clicking and dragging
  3. Pan with Shift + drag
  4. Box or lasso select points
  5. Reset with a double-click

Plotly Toolbar Controls ๐Ÿ–ฑ๏ธ

  • ๐Ÿ“ท Download the plot as PNG
  • ๐Ÿ” Zoom, pan, and select points
  • ๐Ÿ  Reset axes to original view
  • โš™๏ธ Toggle spike lines and axis hover

Part 2: Scatter Plots

Basic Scatter Plot ๐Ÿ“Š

Exploring Relationships Between Variables

library(plotly)

# Basic scatter plot
fig <- plot_ly(data = iris,
               x = ~Sepal.Length,
               y = ~Petal.Length,
               type = 'scatter',
               mode = 'markers')

fig

Result: Basic Scatter Plot ๐Ÿ“Š

Customize Scatter Plot Markers ๐ŸŽจ

Tip

Adjust marker size, fill, and outline to make points easier to distinguish.

Customizing Markers:

# Add color, size, and opacity
fig <- plot_ly(data = iris,
               x = ~Sepal.Length,
               y = ~Petal.Length,
               type = 'scatter',
               mode = 'markers',
               marker = list(size = 10,
                           color = 'rgba(255, 182, 193, .9)',
                           line = list(color = 'rgba(152, 0, 0, .8)',
                                      width = 2)))
fig

Result: Custom Markers ๐ŸŽจ

Color Points by Category ๐ŸŽจ

Adding Color Dimension

Visualize a third variable with color

fig <- plot_ly(iris, x = ~Sepal.Length, y = ~Petal.Length,
               color = ~Species, type = 'scatter', mode = 'markers')
fig

Result: Color by Species ๐ŸŽจ

Add Labels and Choose Colors ๐ŸŽจ

fig <- fig %>% layout(
  title = "Iris Dataset: Sepal vs Petal Length",
  xaxis = list(title = "Sepal Length (cm)"),
  yaxis = list(title = "Petal Length (cm)")
)

fig

Color Options:

  • color = ~variable: map a variable to color
  • colors = 'Set1': use an RColorBrewer palette
  • colors = c(...): provide custom colors

Result: Labeled Scatter Plot ๐Ÿท๏ธ

Scatter with Custom Hover ๐Ÿ”

Tip

Customize Tooltip Information

# Custom hover text
fig <- plot_ly(data = iris,
               x = ~Sepal.Length,
               y = ~Petal.Length,
               color = ~Species,
               type = 'scatter',
               mode = 'markers',
               text = ~paste("Species:", Species,
                           "<br>Sepal Width:", Sepal.Width,
                           "<br>Petal Width:", Petal.Width),
               hoverinfo = 'text')

fig

Choose What Appears on Hover ๐Ÿ”

Note

Use hoverinfo to show only the details that help explain the plot.

Hover Options:

  • hoverinfo = 'x': Show only x value
  • hoverinfo = 'y': Show only y value
  • hoverinfo = 'x+y': Show both coordinates
  • hoverinfo = 'text': Show custom text
  • hoverinfo = 'none': Disable hover

Scatter with Trend Line ๐Ÿ“ˆ

Adding Statistical Models

library(plotly)
library(dplyr)

# Calculate linear model
model <- lm(Petal.Length ~ Sepal.Length, data = iris)
iris$predicted <- predict(model)

# Plot with trend line
fig <- plot_ly(data = iris, x = ~Sepal.Length) %>%
  add_markers(y = ~Petal.Length, name = 'Actual',
              marker = list(size = 8, opacity = 0.6)) %>%
  add_lines(y = ~predicted, name = 'Trend',
            line = list(color = 'red', width = 2)) %>%
  layout(title = "Scatter Plot with Linear Regression",
         xaxis = list(title = "Sepal Length"),
         yaxis = list(title = "Petal Length"))

fig

Result: Scatter with Trend Line ๐Ÿ“ˆ

Part 3: Box Plots

Basic Box Plot ๐Ÿ“ฆ

Note

Visualizing Distributions โ€” Box plots show median, quartiles, and outliers

# Simple box plot
fig <- plot_ly(data = iris,
               y = ~Sepal.Length,
               type = 'box',
               name = 'Sepal Length')

fig

Result: Basic Box Plot ๐Ÿ“ฆ

Read a Box Plot ๐Ÿ“ฆ

Note

The box summarizes the distribution; points beyond the whiskers are outliers.

  • Box: Interquartile range (IQR) - middle 50% of data
  • Line in Box: Median (50th percentile)
  • Whiskers: Extend to 1.5 ร— IQR
  • Points: Outliers beyond whiskers
  • Hover to inspect exact values

Grouped Box Plots ๐Ÿ“Š

Comparing Multiple Groups

# Box plot by species
fig <- plot_ly(data = iris,
               y = ~Sepal.Length,
               x = ~Species,
               color = ~Species,
               type = 'box')

fig <- fig %>% layout(
  title = "Sepal Length Distribution by Species",
  xaxis = list(title = "Species"),
  yaxis = list(title = "Sepal Length (cm)")
)

fig

Result: Grouped Box Plots ๐Ÿ“Š

Show Individual Values on Box Plots ๐Ÿ”Ž

Tip

Jitter spreads points horizontally so overlapping observations are easier to see.

# Show points on box plot
fig <- plot_ly(data = iris,
               y = ~Sepal.Length,
               x = ~Species,
               color = ~Species,
               type = 'box',
               boxpoints = 'all',        # Show all points
               jitter = 0.3,             # Spread points horizontally
               pointpos = -1.8)          # Position of points

fig

Result: Box Plot with Points ๐Ÿ”Ž

Horizontal Box Plots ๐Ÿ”„

Tip

Better for Long Category Names

# Horizontal orientation
fig <- plot_ly(data = iris,
               x = ~Sepal.Length,        # x for horizontal
               y = ~Species,             # y for categories
               color = ~Species,
               type = 'box',
               orientation = 'h')        # h for horizontal

fig <- fig %>% layout(
  title = "Sepal Length by Species (Horizontal)",
  xaxis = list(title = "Sepal Length (cm)"),
  yaxis = list(title = "")
)

fig

Result: Horizontal Box Plots ๐Ÿ”„

Multiple Box Plots ๐Ÿ“ˆ

Note

Comparing Different Measurements

# Create subplot with multiple box plots
fig <- plot_ly(data = iris, x = ~Species) %>%
  add_trace(y = ~Sepal.Length, name = 'Sepal Length',
            type = 'box', boxmean = 'sd') %>%
  add_trace(y = ~Sepal.Width, name = 'Sepal Width',
            type = 'box', boxmean = 'sd') %>%
  add_trace(y = ~Petal.Length, name = 'Petal Length',
            type = 'box', boxmean = 'sd') %>%
  add_trace(y = ~Petal.Width, name = 'Petal Width',
            type = 'box', boxmean = 'sd') %>%
  layout(title = "All Iris Measurements by Species",
         yaxis = list(title = "Measurement (cm)"))

fig

Result: Multiple Box Plots ๐Ÿ“ˆ

Show the Mean on a Box Plot ๐Ÿ“ˆ

Note

Set boxmean = 'sd' to show the mean and standard deviation.

Part 4: Histograms

Basic Histogram ๐Ÿ“Š

Distribution of a Single Variable

# Simple histogram
fig <- plot_ly(x = ~iris$Sepal.Length,
               type = 'histogram',
               marker = list(color = 'steelblue',
                           line = list(color = 'white', width = 1)))

fig <- fig %>% layout(
  title = "Distribution of Sepal Length",
  xaxis = list(title = "Sepal Length (cm)"),
  yaxis = list(title = "Count")
)

fig

Result: Basic Histogram ๐Ÿ“Š

Histogram Bin Controls ๐Ÿ“Š

Note

Choose the number of bins or specify exact bin boundaries.

  • nbinsx: Number of bins (auto-calculated if not specified)
  • xbins: Manual bin configuration

Understanding Binwidth โš–๏ธ

Warning

Binwidth Matters! The choice of binwidth dramatically affects interpretation

Too Few Bins (Large Binwidth):

# Very few bins - loses detail
fig <- plot_ly(x = ~iris$Sepal.Length,
               type = 'histogram',
               nbinsx = 5)  # Only 5 bins
fig

Advantages: โœ… Clear overall pattern, less noise
Disadvantages: โŒ Loses fine-grained patterns, may hide bimodality

Result: 5 Bins ๐Ÿ“Š

Binwidth: Finding Balance ๐ŸŽฏ

Too Many Bins (Small Binwidth):

# Too many bins - too noisy
fig <- plot_ly(x = ~iris$Sepal.Length,
               type = 'histogram',
               nbinsx = 50)  # 50 bins
fig

Advantages: โœ… Shows fine detail, reveals minor peaks
Disadvantages: โŒ Noisy, harder to see overall pattern, sparse bins

Result: 50 Bins ๐Ÿ“Š

Choosing a Binwidth ๐ŸŽจ

Tip

Rules of Thumb for Choosing Bins

Common Rules:

  1. Sturgesโ€™ Rule: bins โ‰ˆ logโ‚‚(n) + 1
  2. Square Root: bins โ‰ˆ โˆšn
  3. Scottโ€™s Rule: binwidth โ‰ˆ 3.5ฯƒ / โˆ›n
  4. Freedman-Diaconis: binwidth โ‰ˆ 2IQR / โˆ›n

Try an Automatic Binwidth ๐ŸŽจ

Tip

Plotly chooses a default binning; compare it with other choices to see which best tells the dataโ€™s story.

# Good balance - auto-calculated
fig <- plot_ly(x = ~iris$Sepal.Length,
               type = 'histogram',
               marker = list(color = 'lightgreen',
                           line = list(color = 'darkgreen', width = 1)))
fig  # Plotly uses smart defaults!

Result: Automatic Binwidth ๐ŸŽจ

Custom Binwidth ๐Ÿ”ง

Note

Manual Control Over Bins

# Specify exact bin size
fig <- plot_ly(x = ~iris$Sepal.Length,
               type = 'histogram',
               xbins = list(
                 start = 4.0,     # First bin starts at 4
                 end = 8.0,       # Last bin ends at 8
                 size = 0.2       # Each bin is 0.2 cm wide
               ))

fig <- fig %>% layout(
  title = "Sepal Length with 0.2 cm Bins",
  xaxis = list(title = "Sepal Length (cm)"),
  yaxis = list(title = "Frequency")
)

fig

Result: Custom Binwidth ๐Ÿ”ง

Overlaid Histograms ๐Ÿ“Š

Comparing Distributions

# Create separate data for each species
setosa <- iris %>% filter(Species == "setosa")
versicolor <- iris %>% filter(Species == "versicolor")
virginica <- iris %>% filter(Species == "virginica")

# Overlaid histograms
fig <- plot_ly(alpha = 0.6) %>%
  add_histogram(x = ~setosa$Sepal.Length, name = "Setosa") %>%
  add_histogram(x = ~versicolor$Sepal.Length, name = "Versicolor") %>%
  add_histogram(x = ~virginica$Sepal.Length, name = "Virginica") %>%
  layout(barmode = "overlay",          # Overlay instead of stack
         title = "Sepal Length by Species",
         xaxis = list(title = "Sepal Length (cm)"),
         yaxis = list(title = "Count"))

fig

Other barmode options: 'stack', 'group'

Result: Overlaid Histograms ๐Ÿ“Š

Stacked Histograms ๐Ÿ“š

Tip

Showing Composition

# Stacked histogram
fig <- plot_ly() %>%
  add_histogram(x = ~setosa$Sepal.Length, 
                name = "Setosa",
                marker = list(color = '#e74c3c')) %>%
  add_histogram(x = ~versicolor$Sepal.Length,
                name = "Versicolor",
                marker = list(color = '#3498db')) %>%
  add_histogram(x = ~virginica$Sepal.Length,
                name = "Virginica",
                marker = list(color = '#2ecc71')) %>%
  layout(barmode = "stack",
         title = "Species Distribution Across Sepal Lengths",
         xaxis = list(title = "Sepal Length (cm)"),
         yaxis = list(title = "Total Count"))

fig

Result: Stacked Histograms ๐Ÿ“š

Part 5: Other Plot Types

Bar Charts ๐Ÿ“Š

Note

Categorical Data Visualization

# Count by species
species_count <- iris %>%
  group_by(Species) %>%
  summarise(Count = n())

fig <- plot_ly(data = species_count,
               x = ~Species,
               y = ~Count,
               type = 'bar',
               marker = list(color = c('#e74c3c', '#3498db', '#2ecc71')))

fig <- fig %>% layout(
  title = "Sample Count by Species",
  xaxis = list(title = "Species"),
  yaxis = list(title = "Number of Samples")
)

fig

Result: Bar Chart ๐Ÿ“Š

Line Charts ๐Ÿ“ˆ

Time Series and Trends

iris_sorted <- iris %>% arrange(Sepal.Length)
fig <- plot_ly(iris_sorted, x = ~seq_along(Sepal.Length),
               y = ~Sepal.Length, color = ~Species,
               type = 'scatter', mode = 'lines+markers',
               line = list(width = 2), marker = list(size = 6)) %>%
  layout(title = "Sepal Length Sorted Values",
         xaxis = list(title = "Sample Index"),
         yaxis = list(title = "Sepal Length (cm)"))
fig

Result: Line Chart ๐Ÿ“ˆ

Violin Plots ๐ŸŽป

Tip

Density + Box Plot Combined

# Violin plot shows distribution shape
fig <- plot_ly(data = iris,
               x = ~Species,
               y = ~Sepal.Length,
               color = ~Species,
               type = 'violin',
               box = list(visible = TRUE),     # Show box plot inside
               meanline = list(visible = TRUE)) # Show mean line

fig <- fig %>% layout(
  title = "Sepal Length Distribution (Violin Plot)",
  xaxis = list(title = "Species"),
  yaxis = list(title = "Sepal Length (cm)")
)

fig

Violin plots show the full probability density, making them superior to box plots for multimodal distributions!

Result: Violin Plot ๐ŸŽป

Heatmaps ๐Ÿ”ฅ

Note

Correlation Matrix Visualization

iris_numeric <- iris %>% select(-Species)
cor_matrix <- cor(iris_numeric)
fig <- plot_ly(x = colnames(cor_matrix), y = rownames(cor_matrix),
               z = cor_matrix, type = "heatmap",
               colors = colorRamp(c("blue", "white", "red"))) %>%
  layout(title = "Iris Feature Correlation Matrix",
         xaxis = list(title = ""), yaxis = list(title = ""))
fig

Result: Heatmap ๐Ÿ”ฅ

3D Scatter Plots ๐ŸŒ

Three-Dimensional Data

fig <- plot_ly(iris, x = ~Sepal.Length, y = ~Sepal.Width,
               z = ~Petal.Length, color = ~Species,
               type = 'scatter3d', mode = 'markers',
               marker = list(size = 5)) %>%
  layout(scene = list(
    xaxis = list(title = 'Sepal Length'),
    yaxis = list(title = 'Sepal Width'),
    zaxis = list(title = 'Petal Length')),
    title = "3D Iris Visualization")
fig

Interactivity is KEY! Rotate the plot by clicking and dragging!

Part 6: Customization & Styling

Layout Customization ๐ŸŽจ

Tip

Fine-Tuning Your Plots

fig <- plot_ly(iris, x = ~Sepal.Length, y = ~Petal.Length,
               color = ~Species, type = 'scatter', mode = 'markers')
fig <- fig %>% layout(
  title = list(text = "Beautiful Iris Plot",
               font = list(size = 24, color = '#2c3e50')),
  xaxis = list(title = "Sepal Length (cm)", gridcolor = '#E0E0E0',
               showline = TRUE, linecolor = '#2c3e50', linewidth = 2),
  yaxis = list(title = "Petal Length (cm)", gridcolor = '#E0E0E0'),
  plot_bgcolor = '#F8F9FA', paper_bgcolor = '#FFFFFF')
fig

Result: Layout Customization ๐ŸŽจ

Color Scales ๐ŸŒˆ

Note

Using Color Effectively

# Color by continuous variable
fig <- plot_ly(data = iris,
               x = ~Sepal.Length,
               y = ~Petal.Length,
               color = ~Sepal.Width,      # Continuous color
               type = 'scatter',
               mode = 'markers',
               marker = list(size = 10,
                           colorbar = list(title = "Sepal Width")))

fig <- fig %>% layout(title = "Color by Sepal Width")
fig

Result: Continuous Color Scale ๐ŸŒˆ

Choose a Color Scale ๐ŸŒˆ

Note

Use a palette that helps readers distinguish values without distracting from the data.

Built-in Color Scales:

  • colors = 'Viridis', 'Blues', 'Reds', 'RdBu'
  • Or use custom: colors = colorRamp(c("blue", "yellow", "red"))

Add an Annotation ๐Ÿ“

Add a text label and arrow to call attention to a data point.

fig <- plot_ly(data = iris,
               x = ~Sepal.Length,
               y = ~Petal.Length,
               type = 'scatter',
               mode = 'markers') %>%
  layout(
    title = "Annotated Plot",
    annotations = list(
      list(x = 6.5, y = 5.5,
           text = "Cluster of large flowers",
           showarrow = TRUE,
           arrowhead = 2,
           arrowcolor = "red"))
  )

fig

Result: Annotated Plot ๐Ÿ“

Highlight a Region with a Shape ๐ŸŸฅ

Tip

Use a transparent rectangle to mark an area of the plot without hiding the data.

fig <- plot_ly(data = iris,
               x = ~Sepal.Length,
               y = ~Petal.Length,
               type = 'scatter',
               mode = 'markers') %>%
  layout(
    shapes = list(
      list(type = "rect",
           x0 = 6, x1 = 7, y0 = 5, y1 = 6,
           line = list(color = "red", width = 2),
           fillcolor = "rgba(255, 0, 0, 0.1)")
    )
  )

fig

Result: Highlighted Region ๐ŸŸฅ

Subplots ๐Ÿ“Š๐Ÿ“Š

Tip

Multiple Plots in One Figure

library(plotly)

# Create individual plots
p1 <- plot_ly(iris, x = ~Sepal.Length, type = "histogram",
              name = "Sepal Length")
p2 <- plot_ly(iris, x = ~Petal.Length, type = "histogram",
              name = "Petal Length")
p3 <- plot_ly(iris, x = ~Sepal.Length, y = ~Petal.Length,
              color = ~Species, type = "scatter", mode = "markers")
p4 <- plot_ly(iris, x = ~Species, y = ~Sepal.Length,
              color = ~Species, type = "box")

Combine Plots in a Grid ๐Ÿ“Š

Tip

After defining p1 through p4, arrange them in a 2 ร— 2 layout.

# Combine into subplot
fig <- subplot(p1, p2, p3, p4,
               nrows = 2, ncols = 2,
               shareX = FALSE, shareY = FALSE,
               titleX = TRUE, titleY = TRUE)

fig <- fig %>% layout(title = "Iris Dataset Overview",
                     showlegend = FALSE)
fig

Part 7: Interactive Code Generator

Plotly Code Generator ๐Ÿ› ๏ธ

Build Your Own Plotly Visualization!

Interactive tool to generate Plotly code for different plot types

Plotly Code Generator

Click "Generate Code" to create your Plotly code!

Try the Generator! ๐ŸŽฎ

Tip

Interactive Learning โ€” Experiment with the controls and inspect the generated code.

Try these options:

  • Switch datasets and plot types
  • Add a color variable and choose a color scale
  • Generate and copy the code

Try it: Generate code for a 3D scatter plot of iris data colored by Species!

Part 8: Best Practices

When to Use Plotly ๐Ÿค”

Note

Choosing the Right Tool

Choose Plotly for:

โœ… Interactive dashboards and web apps
โœ… Exploratory data analysis
โœ… Presentations where you can click and zoom
โœ… Sharing HTML reports
โœ… 3D visualizations

When to Use ggplot2 ๐Ÿค”

Note

Choose a static plot when publication control matters most.

โœ… Publication-quality static graphics
โœ… Fine-grained control over every element
โœ… Complex multi-layered plots
โœ… PDF/PNG exports for papers
โœ… Faceted plots with many panels

Need both? Convert a ggplot with ggplotly().

Converting ggplot2 to Plotly ๐Ÿ”„

The Power of ggplotly()

library(ggplot2)
library(plotly)

# Create a ggplot
p <- ggplot(iris, aes(x = Sepal.Length, y = Petal.Length, 
                     color = Species)) +
  geom_point(size = 3) +
  theme_minimal() +
  labs(title = "Iris Dataset",
       x = "Sepal Length (cm)",
       y = "Petal Length (cm)")

# Convert to interactive Plotly plot
ggplotly(p)

Advantages:

  • Keeps all your ggplot2 customization
  • Automatically adds interactivity
  • One line of code!

Performance Tips ๐Ÿš€

Warning

Making Plotly Fast

For Large Datasets:

# 1. Use webgl for better performance
fig <- plot_ly(data = large_dataset,
               x = ~x, y = ~y,
               type = 'scattergl',  # Note: scattergl instead of scatter
               mode = 'markers')

# 2. Reduce marker count with sampling
sampled <- large_dataset %>% sample_n(1000)
fig <- plot_ly(data = sampled, ...)

# 3. Disable hover for thousands of points
fig <- plot_ly(..., hoverinfo = 'skip')

Keep Large Plots Responsive โšก

Note

Choose a rendering strategy that matches the size of your data.

Tips:

  • Use scattergl for >1000 points
  • Consider aggregation or binning for huge datasets
  • Disable unnecessary interactive features

Saving Plotly Plots ๐Ÿ’พ

Tip

Export Options

library(plotly)
library(htmlwidgets)

# Create a plot
fig <- plot_ly(iris, x = ~Sepal.Length, y = ~Petal.Length,
               color = ~Species, type = 'scatter', mode = 'markers')

# Save as interactive HTML
htmlwidgets::saveWidget(fig, "my_plot.html")

Export a Static Image ๐Ÿ–ผ๏ธ

Tip

Static PNG export requires a configured image engine such as Kaleido.

# install.packages("reticulate")
# reticulate::py_install("kaleido")
library(orca)
orca(fig, "my_plot.png")

Embed a Plot in a Report ๐Ÿ“„

Note

In an R Markdown or Quarto document, print the plot object to include it.

fig

Key Takeaways: Core Ideas ๐ŸŽฏ

Note

What We Learned

1. Installation: Use install.packages('plotly') and setup functions

2. Basic Syntax:

plot_ly(data = df, x = ~var1, y = ~var2, type = 'scatter')

3. Plot Types: - Scatter, Box, Histogram, Bar, Line, Violin, Heatmap, 3D

4. Binwidths: - Too few bins โ†’ lose detail - Too many bins โ†’ too noisy - Use Plotlyโ€™s smart defaults or calculate optimal bins

Key Takeaways: Customize and Extend ๐ŸŽจ

Note

Make plots clearer and shareable

5. Customization: - layout() for axes, titles, colors - add_trace() for multiple layers - Annotations and shapes for context

Practice Challenge ๐Ÿ†

Tip

Try This on Your Own!

Challenge: Create an interactive Plotly visualization using the mtcars dataset

Requirements:

  1. Create a scatter plot of mpg vs wt (weight)
  2. Color points by cyl (cylinders)
  3. Add custom hover text showing car name and horsepower
  4. Include a title and axis labels
  5. Customize the color scheme

Practice Challenge: Bonus Ideas ๐Ÿ†

Tip

Try an extension after the required scatter plot is complete.

Bonus:

  • Add a trend line
  • Create a subplot with a histogram of mpg
  • Make it 3D by adding disp as z-axis

Time: 5-10 minutes

Resources ๐Ÿ“š

Continue Learning

Documentation: Plotly R ยท Graph reference ยท Community forum

Tutorials: Getting started ยท Plotly book ยท R Graph Gallery

Cheat sheet: Plotly R PDF

So What Did We Cover, Again?

Note

Keep Exploring!

You now know how to:

โœ… Install and set up Plotly
โœ… Create interactive scatter, box, and histogram plots
โœ… Choose appropriate binwidths
โœ… Customize plots with colors, layouts, and themes
โœ… Use the code generator for quick starts
โœ… Convert ggplot2 plots to interactive Plotly plots

What to Try Next ๐Ÿš€

Note

Keep exploring with your own data

Next Steps:

  • Practice with your own datasets
  • Explore advanced plot types (sunburst, sankey, etc.)
  • Build interactive dashboards with Shiny + Plotly
  • Share your visualizations on the web!

Happy Plotting! ๐Ÿ“Šโœจ