plot() (Basic Graphs)
R's plot() function is a general-purpose plotting function that can draw scatter plots, line graphs, and more with a single call. Arguments control axis labels, titles, point colors, line types, and more. Combined with png(), it can save graphs to PNG files.
Syntax
# -----------------------------------------------
# plot() — general-purpose plotting function
# -----------------------------------------------
plot(x, y,
type = "p", # plot type (see below)
main = "Title", # title string at the top of the graph
xlab = "X label", # x-axis label
ylab = "Y label", # y-axis label
col = "black", # color of points/lines (name / "#RRGGBB" / integer)
pch = 1, # point shape (integer 1-25)
lty = 1, # line type (1=solid, 2=dashed, 3=dotted, etc.)
lwd = 1, # line width (larger = thicker)
cex = 1, # size multiplier for points/text (1 = standard)
xlim = c(min, max), # x-axis range
ylim = c(min, max) # y-axis range
)
# -----------------------------------------------
# Adding to an existing graph
# -----------------------------------------------
points(x, y, ...) # add points to an existing graph
lines(x, y, ...) # add a line to an existing graph
text(x, y, labels, ...) # add text labels at given coordinates
legend(x, y, legend, ...) # add a legend
# -----------------------------------------------
# Saving to a PNG file
# -----------------------------------------------
png("output.png", width = 800, height = 600)
plot(x, y, ...) # plot commands go here
dev.off() # close the device and write the file
Syntax Reference
| Argument / Function | Description |
|---|---|
type = "p" | Points only (default). Used for scatter plots. |
type = "l" | Lines only. Points are not drawn. |
type = "b" | Both points and lines (both). |
type = "o" | Points and lines overplotted. |
type = "n" | Draws axes only, no points or lines. Used when adding elements later. |
col | Color of points or lines. Accepts color names ("red"), hex codes ("#FF0000"), or integers (2). |
pch | Point shape as an integer. 1=circle, 16=filled circle, 17=triangle, 15=square, etc. |
lty | Line type as an integer. 1=solid, 2=dashed, 3=dotted, 4=dot-dash. |
lwd | Line width as a number. Default is 1; larger values produce thicker lines. |
cex | Size multiplier for points or text. 1.5 makes them 1.5 times larger. |
xlim / ylim | Axis range as a vector c(min, max). |
main / xlab / ylab | Title, x-axis label, and y-axis label strings. |
points(x, y) | Adds points to an existing graph. Accepts the same arguments as plot(). |
lines(x, y) | Adds a line to an existing graph. |
text(x, y, labels) | Draws text labels at given coordinates. The pos argument adjusts placement (above/below/left/right). |
legend(x, y, legend) | Adds a legend. Match the col, pch, and lty arguments to the plot. |
png(file, width, height) | Opens a PNG output device. All drawing until dev.off() is written to the file. |
dev.off() | Closes the current graphics device. Used in conjunction with png(). |
Sample Code
dragonball_plot_basic.R
# dragonball_plot_basic.R — sample demonstrating plot() basics
# Uses Dragon Ball character data to explore
# scatter plots, line graphs, labels, colors, and legends
# -----------------------------------------------
# Prepare data
# -----------------------------------------------
characters <- c("Son Goku", "Vegeta", "Piccolo", "Trunks", "Frieza")
# Power levels (before training)
power_before <- c(9000, 8500, 3500, 5000, 530000)
# Power levels (after training)
power_after <- c(150000, 120000, 42000, 75000, 1500000)
# Training period (weeks)
training_weeks <- c(52, 48, 60, 30, 20)
# -----------------------------------------------
# Open PNG device
# -----------------------------------------------
png("dragonball_plot_basic.png", width = 900, height = 700)
# -----------------------------------------------
# Scatter plot: training weeks vs power growth rate
# -----------------------------------------------
growth_rate <- power_after / power_before
# type="n" draws axes only; points are added afterward
plot(
training_weeks, growth_rate,
type = "n",
main = "Dragon Ball Character Training Efficiency",
xlab = "Training Period (weeks)",
ylab = "Power Growth Rate",
xlim = c(0, 70),
ylim = c(0, max(growth_rate) * 1.1),
las = 1
)
# Add points with individual colors and shapes
point_colors <- c("#E8821A", "#1A6CE8", "#228B22", "#9B30FF", "#CC2200")
point_pch <- c(16, 17, 15, 18, 16)
for (i in seq_along(characters)) {
points(
training_weeks[i], growth_rate[i],
col = point_colors[i],
pch = point_pch[i],
cex = 2.0
)
}
# Add character name labels above each point
text(
training_weeks, growth_rate,
labels = characters,
pos = 3,
cex = 0.9,
col = point_colors
)
# Add a legend
legend(
"topright",
legend = characters,
col = point_colors,
pch = point_pch,
pt.cex = 1.5,
bty = "n"
)
# -----------------------------------------------
# Close the device and write the file
# -----------------------------------------------
dev.off()
cat("=== Scatter plot saved ===\n")
cat("File: dragonball_plot_basic.png\n\n")
# -----------------------------------------------
# Line graph: power level changes
# -----------------------------------------------
png("dragonball_plot_line.png", width = 900, height = 600)
# log="y" uses a log scale on the y-axis (values span many orders of magnitude)
plot(
c(1, 2),
c(power_before[1], power_after[1]),
type = "b",
main = "Dragon Ball Character Power Changes (log scale)",
xlab = "",
ylab = "Power Level (log scale)",
log = "y",
xlim = c(0.8, 2.2),
ylim = c(min(power_before) * 0.5, max(power_after) * 2),
xaxt = "n",
col = point_colors[1],
pch = point_pch[1],
lwd = 2,
cex = 1.8
)
axis(1, at = c(1, 2), labels = c("Before", "After"))
for (i in 2:length(characters)) {
lines(
c(1, 2),
c(power_before[i], power_after[i]),
col = point_colors[i],
lwd = 2,
lty = i
)
points(
c(1, 2),
c(power_before[i], power_after[i]),
col = point_colors[i],
pch = point_pch[i],
cex = 1.8
)
}
legend(
"topleft",
legend = characters,
col = point_colors,
pch = point_pch,
lty = seq_along(characters),
lwd = 2,
pt.cex = 1.5,
bty = "n"
)
dev.off()
cat("=== Line graph saved ===\n")
cat("File: dragonball_plot_line.png\n\n")
# -----------------------------------------------
# Display results
# -----------------------------------------------
cat("--- Character power level data ---\n")
result <- data.frame(
Character = characters,
Power_Before = power_before,
Power_After = power_after,
Growth_Rate = round(growth_rate, 1),
Training_Weeks = training_weeks
)
print(result, row.names = FALSE)
Rscript dragonball_plot_basic.R === Scatter plot saved === File: dragonball_plot_basic.png === Line graph saved === File: dragonball_plot_line.png --- Character power level data --- Character Power_Before Power_After Growth_Rate Training_Weeks Son Goku 9000 150000 16.7 52 Vegeta 8500 120000 14.1 48 Piccolo 3500 42000 12.0 60 Trunks 5000 75000 15.0 30 Frieza 530000 1500000 2.8 20
Common Mistakes
Mistake 1: Forgetting dev.off() after png(), resulting in a corrupted file
After opening a device with png(), if dev.off() is not called, the file write is never completed and the PNG file is left in a corrupted state. The same happens if the script terminates early due to an error. Writing on.exit(dev.off()) immediately after opening the device ensures it is always closed.
plot_devoff_mistake.R
# Problem pattern: omitting dev.off() leaves the file incomplete
png("output.png", width = 800, height = 600)
plot(1:5, c(9000, 8500, 3500, 5000, 530000),
main = "Power Level", type = "b")
# Without dev.off() the file is incomplete
# Correct pattern: use on.exit() to guarantee closure
png("output.png", width = 800, height = 600)
on.exit(dev.off()) # runs even if an error occurs
plot(1:5, c(9000, 8500, 3500, 5000, 530000),
main = "Power Level", type = "b")
Mistake 2: Setting xlim / ylim too narrow so data falls outside the range
When xlim or ylim is set narrower than the actual data range, points outside the range are simply not drawn. This is especially easy to miss when one value is much larger than the others and the range is set as a fixed value without checking the data.
plot_xlim_mistake.R
power <- c(9000, 8500, 3500, 5000, 530000) # Frieza's value is far higher
x <- 1:5
# Problem pattern: Frieza (530000) is outside ylim and not shown
plot(x, power, ylim = c(0, 100000), main = "ylim too narrow")
# Correct pattern: derive the range from the data
plot(x, power,
ylim = c(0, max(power) * 1.1),
main = "ylim derived from data")
Mistake 3: Misspelling a color name in the col argument
Color names passed to the col argument are English strings, and a misspelled name is treated as NA, producing a warning. Using hex codes ("#FF0000") avoids spelling errors. The full list of valid color names can be checked with colors().
plot_col_mistake.R
x <- 1:3 y <- c(9000, 8500, 3500) # Problem pattern: "scarlett" is not a valid color name plot(x, y, col = "scarlett", pch = 16, cex = 2) # Correct patterns: use a valid color name or a hex code plot(x, y, col = "red", pch = 16, cex = 2) # color name plot(x, y, col = "#CC2200", pch = 16, cex = 2) # hex code (more reliable)
Warning message: In plot.xy(xy, type, ...) : invalid color name 'scarlett'
Overview
R's plot() function switches between scatter plot ("p"), line graph ("l"), and combined forms ("b" / "o") using the type argument. Drawing axes only with type = "n" and then layering elements with points() and lines() makes it easy to build composite graphs with different colors and shapes per character. The pos argument of text() (1=below, 2=left, 3=above, 4=right) positions labels, and legend() adds a legend. For data spanning many orders of magnitude, log = "y" applies a log scale to the y-axis. To save a graph to a file, open a device with png(), draw the graph, and close the device with dev.off(). For more specialized charts, see Histogram (hist) and Bar Plot (barplot).
If you find any errors or copyright issues, please contact us.