Chapter 35: R Graphics
R Graphics — one of the most exciting (and sometimes frustrating) parts of R.
R has always been famous for its graphics capabilities — people choose R over other tools precisely because it can produce publication-quality plots, custom infographics, and interactive dashboards. In 2026, the landscape is very clear: there are two main systems, and almost everyone ends up using both at different moments.
I’ll explain it like we’re sitting together in RStudio — slowly, with lots of copy-paste examples, comparisons, pros/cons, and the modern workflow most people use right now.
1. The Two Worlds of R Graphics (2026 Reality)
| System | Package(s) | When people use it (2026) | Learning curve | Speed (simple plots) | Customization power | Publication quality | Interactive? |
|---|---|---|---|---|---|---|---|
| Base R | Built-in (graphics, grDevices, lattice) | Quick checks, residuals, very simple plots, legacy code | Low | Very fast | Medium | Good (but dated look) | No |
| ggplot2 | ggplot2 (tidyverse) | Almost everything: reports, papers, dashboards, Shiny | Medium | Slower (but acceptable) | Extremely high | Excellent (modern, clean) | No (but extensions yes) |
Quick verdict 2026:
- Use base R for fast exploratory plots (like plot(), hist(), boxplot())
- Use ggplot2 for everything you want to share, publish, or polish (99% of final graphics)
2. Base R Graphics – Quick & Built-in
These functions live in base R — no install.packages() needed.
Classic examples (run these right now!)
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 |
# 1. Simple scatter plot plot(iris$Sepal.Length, iris$Petal.Length, main = "Iris Sepal vs Petal (Base R)", xlab = "Sepal Length (cm)", ylab = "Petal Length (cm)", pch = 19, col = iris$Species, cex = 1.2) legend("topleft", legend = levels(iris$Species), col = 1:3, pch = 19) |
→ Fast, but legend is manual, colors are default, looks a bit 1990s.
Histogram & boxplot
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
# Histogram hist(iris$Sepal.Width, breaks = 20, main = "Sepal Width Distribution", xlab = "Sepal Width (cm)", col = "lightblue", border = "black") # Boxplot by group boxplot(Sepal.Length ~ Species, data = iris, main = "Sepal Length by Species", ylab = "Sepal Length (cm)", col = "lightgreen") |
Line plot (time series style)
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
# Fake Hyderabad temperature time series days <- 1:10 temps <- c(28.5, 29.2, 30.1, 31.4, 32.0, 30.8, 29.5, 28.9, 30.2, 31.0) plot(days, temps, type = "o", pch = 16, col = "red", main = "Hyderabad Daily Temp (Feb 2026)", xlab = "Day", ylab = "Temperature (°C)", ylim = c(27, 33)) abline(h = 30, col = "blue", lty = 2) # dashed threshold line |
3. ggplot2 – The Modern Standard (Highly Recommended)
ggplot2 follows the Grammar of Graphics philosophy:
- data → the data frame
- aes() → aesthetics (what goes where: x, y, color, size…)
- geom_ → geometric objects (points, lines, bars…)
- + → add layers
Install once (if not already):
|
0 1 2 3 4 5 6 |
install.packages("ggplot2") # or install tidyverse for everything |
Basic scatter plot (compare to base)
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 |
library(ggplot2) ggplot(iris, aes(x = Sepal.Length, y = Petal.Length, color = Species)) + geom_point(size = 3, alpha = 0.8) + # points labs(title = "Iris Sepal vs Petal Length", x = "Sepal Length (cm)", y = "Petal Length (cm)") + theme_minimal() + # clean look scale_color_brewer(palette = "Set1") # nice colors |
→ Automatic legend, better defaults, easy to customize.
Add trend lines
|
0 1 2 3 4 5 6 7 8 9 10 11 |
ggplot(iris, aes(Sepal.Length, Petal.Length, color = Species)) + geom_point(size = 2.5) + geom_smooth(method = "lm", se = TRUE, alpha = 0.2) + # linear fit + confidence theme_light() + facet_wrap(~ Species) + # small multiples labs(title = "Iris Data with Regression Lines") |
Bar plot (Hyderabad style example)
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
# Fake data df <- data.frame( area = c("Gachibowli", "Hitech City", "Banjara Hills", "Kukatpally"), avg_temp = c(30.2, 29.8, 31.1, 28.9), rainfall_mm = c(5, 12, 3, 18) ) ggplot(df, aes(x = area, y = avg_temp, fill = area)) + geom_col() + geom_text(aes(label = paste(avg_temp, "°C")), vjust = -0.5, size = 4) + scale_fill_brewer(palette = "YlOrRd") + theme_minimal() + labs(title = "Average Temperature by Area – Hyderabad Feb 2026", x = NULL, y = "Avg Temp (°C)") + theme(axis.text.x = element_text(angle = 45, hjust = 1)) |
4. Quick Comparison Table (2026 Perspective)
| Feature | Base R | ggplot2 | Winner (most cases) |
|---|---|---|---|
| Speed (simple plot) | Very fast | Slower (but usually < 1 sec) | Base |
| Learning curve | Low at first | Medium (but pays off fast) | Base (day 1) |
| Customization | Possible but manual | Layered, intuitive | ggplot2 |
| Aesthetics (default) | Dated | Modern, publication-ready | ggplot2 |
| Facets / small multiples | Manual | Built-in facet_wrap() / facet_grid() | ggplot2 |
| Themes | Limited | theme_minimal(), theme_bw(), custom themes | ggplot2 |
| Interactive extensions | No | plotly, ggiraph, ggforce | ggplot2 |
| Use in Shiny / dashboards | Possible | Natural fit | ggplot2 |
5. Modern Workflow Recommendation (2026)
- Day-to-day exploration → base R (plot(), hist(), boxplot()) — super quick
- Anything you’ll share (reports, thesis, blogs, presentations) → ggplot2
- Use R Markdown / Quarto to mix code + plots + text → export PDF/HTML/Word
- Extensions you’ll love:
- ggthemes — extra themes (economist, solarized, etc.)
- patchwork — combine multiple ggplots easily
- ggpubr — publication-ready stats on plots
- plotly::ggplotly() — turn ggplot into interactive HTML plot
Your Mini Practice Right Now
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
# Quick base vs ggplot comparison data(mtcars) # Base R plot(mpg ~ wt, data = mtcars, pch = 19, col = factor(cyl), main = "Base R – MPG vs Weight") # ggplot2 version ggplot(mtcars, aes(x = wt, y = mpg, color = factor(cyl))) + geom_point(size = 3) + geom_smooth(method = "loess", se = FALSE) + theme_minimal() + labs(title = "ggplot2 – MPG vs Weight by Cylinders", x = "Weight (1000 lbs)", y = "Miles per Gallon") |
Which one looks nicer to you? 😄
Ready for next?
- Want to go deeper into ggplot2 layers (geoms, scales, themes)?
- Practice saving plots (png, pdf, high-res)?
- Or build a small dashboard-style example with multiple plots?
Just tell me — whiteboard is ready! ☕📈🚀
