hist() / boxplot() / barplot()
In R, hist() draws a histogram, boxplot() draws a box plot, and barplot() draws a bar chart. All three are built into base graphics and require no external packages. Graphs can be displayed on screen or written to a file by combining the drawing functions with a device function such as png().
Syntax
# -----------------------------------------------
# hist() — draw a histogram
# -----------------------------------------------
hist(x,
breaks = "Sturges", # number of bins or a boundary-value vector
main = NULL, # graph title
xlab = NULL, # x-axis label
col = NULL, # bar fill color
border = NULL, # bar border color
freq = TRUE, # TRUE for frequency, FALSE for density
xlim = NULL, # x-axis range as c(min, max)
ylim = NULL # y-axis range as c(min, max)
)
# -----------------------------------------------
# boxplot() — draw a box plot
# -----------------------------------------------
boxplot(x, ..., # pass multiple vectors to compare groups
names = NULL, # labels for each group as a character vector
main = NULL, # graph title
xlab = NULL, # x-axis label
ylab = NULL, # y-axis label
col = NULL, # box fill color
horizontal = FALSE, # TRUE to draw horizontally
notch = FALSE, # TRUE to show notch (confidence interval for median)
outline = TRUE # FALSE to hide outlier points
)
# -----------------------------------------------
# barplot() — draw a bar chart
# -----------------------------------------------
barplot(height, # bar heights as a vector or matrix
names.arg = NULL, # labels for each bar as a character vector
main = NULL, # graph title
xlab = NULL, # x-axis label
ylab = NULL, # y-axis label
col = NULL, # bar fill color
horiz = FALSE, # TRUE to draw horizontally
beside = FALSE, # TRUE for grouped bars instead of stacked
legend.text = NULL # legend text (for matrix height)
)
# -----------------------------------------------
# Writing a graph to a file
# -----------------------------------------------
png("output.png", width = 800, height = 600) # open PNG device
# call drawing functions here
dev.off() # close device and save file
Function / Argument Reference
| Function / Argument | Description |
|---|---|
hist(x) | Draws a histogram of numeric vector x. Returns a list containing bin information. |
hist()$breaks | Returns the bin boundary vector. Use plot=FALSE to obtain interval info without drawing. |
hist()$counts | Returns the count (frequency) of elements in each bin as an integer vector. |
breaks | Specifies the bin-count algorithm ("Sturges", "Scott", "FD"), an integer hint, or a boundary-value vector. |
boxplot(x) | Draws a box plot of numeric vector x. Multiple vectors produce a group comparison. |
boxplot(formula, data) | Draws a box plot from a data frame using formula notation (e.g., score ~ group). |
notch = TRUE | Shows the 95% confidence interval for the median as a notch. Non-overlapping notches indicate a statistically significant difference in medians. |
barplot(height) | Draws a bar chart using a vector or matrix as bar heights. A matrix produces a stacked bar chart by default. |
beside = TRUE | When a matrix is passed to barplot(), draws grouped bars side-by-side instead of stacked. |
legend() | Adds a legend to the graph. Position strings such as "topright" can be used for the x argument. |
png(file) | Opens a PNG file output device. Accepts width, height (pixels) and res (dpi). |
dev.off() | Closes the current graphics device and completes the file write. |
par(mfrow = c(r, c)) | Sets up a layout for drawing multiple graphs in one window (or file). |
Sample Code
kof_plot_histogram_boxplot.R
# kof_plot_histogram_boxplot.R
# Sample using The King of Fighters character data
# to explore hist(), boxplot(), and barplot() basics.
# Graphs are written to a PNG file.
# -----------------------------------------------
# Prepare sample data
# -----------------------------------------------
# Simulated damage scores for KOF characters (50 mock battles each)
# Fix the random seed for reproducibility
set.seed(42)
# Terry Bogard — offensive type: high damage, high variance
terry_dmg <- round(rnorm(50, mean = 280, sd = 45))
# Kyo Kusanagi — balanced type: moderate damage
kyo_dmg <- round(rnorm(50, mean = 260, sd = 35))
# Iori Yagami — offensive type: high damage, high variance
iori_dmg <- round(rnorm(50, mean = 275, sd = 50))
# Mai Shiranui — speed type: lower damage, stable
mai_dmg <- round(rnorm(50, mean = 220, sd = 25))
# Ralf Jones — power type: very high but erratic
ralf_dmg <- round(rnorm(50, mean = 300, sd = 60))
# Character name vector for graph labels
char_names <- c("Terry", "Kyo", "Iori", "Mai", "Ralf")
# -----------------------------------------------
# Output three graphs side-by-side in one PNG
# -----------------------------------------------
png("kof_plot_histogram_boxplot.png", width = 1200, height = 400, res = 96)
# Split the drawing area into 3 columns
par(mfrow = c(1, 3), mar = c(4, 4, 3, 1))
# -----------------------------------------------
# Graph 1: hist() — Terry's damage distribution
# -----------------------------------------------
hist(
terry_dmg,
breaks = 12,
main = "Terry — Damage Distribution",
xlab = "Damage",
ylab = "Frequency",
col = "#e8a000",
border = "white"
)
# Add a vertical line at the mean
abline(v = mean(terry_dmg), col = "red", lwd = 2, lty = 2)
# Add mean label
text(
x = mean(terry_dmg) + 8,
y = par("usr")[4] * 0.9,
labels = paste("Mean:", round(mean(terry_dmg))),
col = "red",
cex = 0.85
)
# -----------------------------------------------
# Graph 2: boxplot() — damage comparison across 5 characters
# -----------------------------------------------
boxplot(
terry_dmg, kyo_dmg, iori_dmg, mai_dmg, ralf_dmg,
names = char_names,
main = "Damage by Character",
ylab = "Damage",
col = c("#e8a000", "#cc2200", "#660099", "#ff6699", "#336699"),
border = "gray30",
notch = FALSE,
las = 2,
cex.axis = 0.85
)
abline(h = 260, col = "gray60", lwd = 1, lty = 3)
# -----------------------------------------------
# Graph 3: barplot() — average damage per character
# -----------------------------------------------
avg_dmg <- c(
mean(terry_dmg),
mean(kyo_dmg),
mean(iori_dmg),
mean(mai_dmg),
mean(ralf_dmg)
)
bar_pos <- barplot(
avg_dmg,
names.arg = char_names,
main = "Average Damage by Character",
ylab = "Average Damage",
col = c("#e8a000", "#cc2200", "#660099", "#ff6699", "#336699"),
border = "white",
ylim = c(0, 380),
las = 2,
cex.names = 0.85
)
# Display numeric values above each bar
text(
x = bar_pos,
y = avg_dmg + 12,
labels = round(avg_dmg, 1),
cex = 0.85,
col = "gray20"
)
dev.off()
cat("Graph written to kof_plot_histogram_boxplot.png\n")
# -----------------------------------------------
# Inspect the return value of hist()
# -----------------------------------------------
cat("\n--- hist() return value ---\n")
# Use the same breaks = 12 as the hist() above for consistent bin information
h <- hist(terry_dmg, breaks = 12, plot = FALSE)
cat("Bin boundaries (breaks):", h$breaks, "\n")
cat("Bin counts (counts): ", h$counts, "\n")
cat("Number of bins: ", length(h$counts), "\n")
# -----------------------------------------------
# Inspect boxplot() statistics (five-number summary)
# -----------------------------------------------
cat("\n--- boxplot() statistics (five-number summary) ---\n")
bp_stats <- boxplot(
terry_dmg, kyo_dmg, iori_dmg, mai_dmg, ralf_dmg,
plot = FALSE
)$stats
rownames(bp_stats) <- c("Min (whisker)", "Q1", "Median", "Q3", "Max (whisker)")
colnames(bp_stats) <- char_names
print(round(bp_stats, 1))
Rscript kof_plot_histogram_boxplot.R
Graph written to kof_plot_histogram_boxplot.png
--- hist() return value ---
Bin boundaries (breaks): 155 170 185 200 215 230 245 260 275 290 305 320 335 350
Bin counts (counts): 1 0 1 1 4 5 8 11 10 5 2 1 1
Number of bins: 13
--- boxplot() statistics (five-number summary) ---
Terry Kyo Iori Mai Ralf
Min (whisker) 174.2 181.7 152.6 163.3 160.7
Q1 252.5 236.5 242.2 204.5 260.0
Median 281.0 260.5 276.0 222.5 299.5
Q3 306.5 282.8 307.5 237.8 335.5
Max (whisker) 374.8 338.3 367.4 280.7 418.3
The five-number summary values are based on random data generated by set.seed(42) + rnorm(). Because random number generation algorithms differ across R versions, the actual output may vary depending on your R version.
Common Mistakes
Mistake 1: Specifying breaks=10 does not guarantee 10 bins
When an integer is passed to the breaks argument, R treats it only as a hint and automatically adjusts the bin boundaries to produce clean interval widths. Specifying breaks=10 may result in 8 or 13 actual bins. To control bin boundaries precisely, pass a boundary-value vector directly instead of an integer.
hist_breaks.R
set.seed(42)
scores <- round(rnorm(50, mean = 280, sd = 45))
# breaks=10 does not guarantee exactly 10 bins
h10 <- hist(scores, breaks = 10, plot = FALSE)
cat("breaks=10 actual bin count:", length(h10$counts), "\n")
# Use a boundary vector for exact 10 bins
bounds <- seq(min(scores), max(scores), length.out = 11)
h_exact <- hist(scores, breaks = bounds, plot = FALSE)
cat("boundary vector bin count:", length(h_exact$counts), "\n")
breaks=10 actual bin count: 13 boundary vector bin count: 10
Mistake 2: outline=FALSE hides outlier points but does not remove the data
outline=FALSE in boxplot() only hides the outlier points in the graph; it does not affect the underlying statistics. Values outside the whisker range remain in the data and can be retrieved via boxplot()$out. If you need to analyze data with outliers excluded, you must filter them from the dataset itself.
boxplot_outline.R
set.seed(42)
dmg <- c(round(rnorm(48, mean = 280, sd = 40)), 500, 50) # two outliers added
# With outline=TRUE (default), outliers are shown as points
bp <- boxplot(dmg, plot = FALSE)
cat("Outliers:", bp$out, "\n")
# outline=FALSE does not change $out
bp2 <- boxplot(dmg, outline = FALSE, plot = FALSE)
cat("Outliers after outline=FALSE:", bp2$out, "\n")
Outliers: 500 50 Outliers after outline=FALSE: 500 50
Overview
R's base graphics includes three drawing functions suited for visualizing numeric distributions. hist() divides data into bins and draws their frequencies as bars. The breaks argument accepts a bin-count algorithm name ("Sturges", etc.), an integer hint, or an exact boundary-value vector. Passing plot=FALSE returns bin information as a list without drawing anything. boxplot() visualizes the five-number summary — minimum, Q1, median, Q3, and maximum — as box-and-whisker plots. Passing multiple vectors enables group comparisons; the formula notation boxplot(score ~ group, data=df) also works directly with data frames. barplot() accepts a vector or matrix as bar heights, drawing a stacked bar chart by default and grouped bars with beside=TRUE. To save a graph to a file, open an output device such as png(), call the drawing functions, then close the device with dev.off(). par(mfrow = c(r, c)) arranges multiple graphs in one file. For scatter plots and line charts, see plot() Basics.
If you find any errors or copyright issues, please contact us.