I have the following toy data
Xeafield (1999) (PER) ,1,0.5745375408
Lancelot et al. (1989),0.9394939494,0.4733405876
LemLM Xeafield (1997) (TER) ,0.6265126513,0.2959738847
Almore and Flemin (2001) (KER),0.4218921892,0.5745375408
Malek et al. (2006) (HER) ,0.4125412541,1
Charles and Osborne (2003),0.0308030803,0.1414581066
And trying a simple 2D plot in R with points labeled using the 1st column.
pdf('data.pdf', width = 7, height = 8)
d1 <- read.csv("data.csv", header=F, dec=".",sep = ",")
plot(as.matrix(d1[,2]), as.matrix(d1[,3]), col= "blue", pch = 19, cex = 1, lty = "solid", lwd = 2, ylim=c(0,1), xaxt = "n",yaxt = "n")
text(as.matrix(d1[,2]), as.matrix(d1[,3]), labels=as.matrix(d1[,1]), cex= 0.7, pos=3)
x_axis_range <- c(0,1)
x_axis_labels <- c("Small","Large")
axis(1,at = x_axis_range, labels = x_axis_labels)
y_axis_range <- c(0,1)
y_axis_labels <- c("Slow","Fast")
axis(2,at = y_axis_range, labels = y_axis_labels)
title(xlab="Memory", ylab="Speed",cex.lab=1)
dev.off()
But the plot doesn't come out right. A few issues I have: the axis label are messed up (it shows as.matrix ..., instead of the label I specified), and the margin of the plot is to small that node labels are cutoff. I am new to using R and plot, appreciate your help.
A simple solution for your problem is to define axis labels and axis ranges in the plot function.
d1 <- structure(list(V1 = structure(c(6L, 3L, 4L, 1L, 5L, 2L), .Label = c("Almore and Flemin (2001) (KER)",
"Charles and Osborne (2003)", "Lancelot et al. (1989)", "LemLM Xeafield (1997) (TER) ",
"Malek et al. (2006) (HER) ", "Xeafield (1999) (PER) "), class = "factor"),
V2 = c(1, 0.9394939494, 0.6265126513, 0.4218921892, 0.4125412541,
0.0308030803), V3 = c(0.5745375408, 0.4733405876, 0.2959738847,
0.5745375408, 1, 0.1414581066)), .Names = c("V1", "V2", "V3"
), class = "data.frame", row.names = c(NA, -6L))
# Use xlab and ylab for axis labels and
# and xlim and ylim for setting axis ranges
plot(as.matrix(d1[,2]), as.matrix(d1[,3]), col= "blue", pch = 19,
cex = 1, lty = "solid", lwd = 2, ylim=c(-0.1,1.1), xaxt = "n",yaxt = "n",
xlab="Memory", ylab="Speed",cex.lab=1, xlim=c(-0.1,1.1))
text(as.matrix(d1[,2]), as.matrix(d1[,3]),
labels=as.matrix(d1[,1]), cex= 0.7, pos=3)
x_axis_range <- c(0,1)
x_axis_labels <- c("Small","Large")
axis(1,at = x_axis_range, labels = x_axis_labels)
y_axis_range <- c(0,1)
y_axis_labels <- c("Slow","Fast")
axis(2,at = y_axis_range, labels = y_axis_labels)
Related
Change secondary line axis color changes send color for ggplot, but I chose to go with base R, and would like to be able to select the second y axis color.
I have the following data:
df = structure(list(A = c("Q4-17", "Q1-18", "Q2-18", "Q3-18", "Q4-18",
"Q1-19", "Q2-19", "Q3-19", "Q4-19", "Q1-20", "Q2-20", "Q3-20",
"Q4-20", "Q1-21", "Q2-21", "Q3-21", "Q4-21", "Q1-22", "Q2-22",
"Q3-22"), B = c(69.45, 71.1, 74.94, 73.87, 93.61, 91.83,
95.38, 109.8, 133.75, 125.26, 118.22, 145.65, 144.9757185, 155.3464032,
184.367033, 179.8121721, 187.235487, 189.1684376, 184.3864519,
161.5300056), C = c(70.73, 71.73, 74.33, 73.27,
95.94, 94.38, 95.38, 109.8, 115.32, 116.92, 115.9, 113.87, 106.108147,
96.84273563, 111.5150869, 110.1228567, 110.7448835, 194.9684376,
187.7241152, 167.7665553), D = c(260.3, 216.02, 203.72,
203.52, 300.96, 320.77, 330.5, 413.52, 436.7, 474.96, 463.6,
501.87, 493.8865461, 497.1760767, 514.9903459, 503.7601267, 510.8362938,
614.9915546, 603.5761107, 593.660831), E = c(NA,
NA, NA, NA, NA, NA, NA, NA, 39.237, 35.621, 32.964, NA, 152.137,
140.743023, 167.809, 170.877, 117.517, 102.691723, 88.8, 76.2445528
)), class = "data.frame", row.names = c(NA, -20L))
df = df %>%
rowwise() %>%
mutate(sums = sum(D,E, na.rm = TRUE))
df = df[8:nrow(df),]
and this to generate my plot
x <- seq(1,nrow(df),1)
y1 <- df$B
y2 <- df$D
par(mar = c(5, 4, 4, 4) + 0.3)
plot(x, y1, col = "#000000",
type = "l",
main = "title",
ylim = c(0, max(df[,2:3])),
ylab = "Y1",
xlab = "",
xaxt = "n")
axis(1,
at = seq(from = 13, by = -4, length.out = 4),
labels = df$A[seq(from = 13, by = -4, length.out = 4)])
lines(x, df$C, lty = "dashed", col = "#adadad", lwd = 2)
par(new = TRUE)
plot(x, df$sums, col = "#ffa500",
axes = FALSE, xlab = "", ylab = "", type = "l")
axis(side = 4, at = pretty(range(y2)),
ylim = c(0,max(df[,3:5], na.rm = TRUE)),
col = "#00aa00") # Add colour selection of 2nd axis
par(new = TRUE)
plot(x, df$D , col = "#0000ff",
axes = FALSE, xlab = "", ylab = "", type = "l", lwd = 1)
mtext("y2", side = 4, line = 3)
but this does not colour my complete second y axis, nor labels, nor title
does any one have any suggestions to be able to set entire y2 axis to be #00AA00 - ticks, labels, and title?
This is my code:
score <- tapply(exams$writing.score
, list(exams$gender,
exams$race.ethnicity
)
, mean)
plot1 <- barplot(score
, beside = TRUE
, main = "Comparison of Writing Score"
, col = c("red", "lightyellow")
, xlab = "Race Ethnicity Group"
, ylab = "Average Writing Score"
, legend.text = c("Female", "Male")
, args.legend = list(x = "topright")
)
As I want to make the box: Female and Male smaller so it does not hide the bar behind. How can I make the legend box smaller? I tried to move it to the top right of the chart, but I do not think it moves.
You could use the argument cex. Here is a reproducible example:
data <- matrix(c(1,2,3,4,5,6,7,8,9,10), ncol = 5)
colnames(data) <- paste0("V", 1:5)
rownames(data) <- c('A','B')
# Normal
barplot(data, col = 1:nrow(data))
legend("topright", legend = rownames(data), pch = 15, col = 1:nrow(data))
# With cex
barplot(data, col = 1:nrow(data))
legend("topright", legend = rownames(data), pch = 15, col = 1:nrow(data), cex = 0.5)
Created on 2022-10-21 with reprex v2.0.2
Another option (in addition to using cex as #Quinten shows) is to also change the inset to move the legend outside of the plot boundary, as well as using par to specify the parameters for margins, etc.
par(mar = c(5, 4, 4, 8),
xpd = TRUE)
# Normal
barplot(df, col = 1:nrow(df))
legend(
"topright",
inset = c(-0.1, 0),
# Create legend outside of plot
legend = rownames(df),
pch = 15,
col = 1:nrow(df),
cex = 0.8
)
Data
df <- structure(c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10), dim = c(2L, 5L), dimnames = list(
c("Female", "Male"), c("V1", "V2", "V3", "V4", "V5")))
It doesn't move because you already are at the very top. To move the top upwards and let the legend follow, expand ylim.
Also try if you like setting the legend horizontal and remove the bty (boxtype). Don't choose the cex too small.
barplot(score
, beside=TRUE
, main="Comparison of Writing Score"
, col=c("red", "lightyellow")
, xlab="Race Ethnicity Group"
, ylab="Average Writing Score"
, legend.text=c("Female", "Male")
, args.legend=list(x="topright", cex=.9, horiz=TRUE, bty='n')
, ylim=c(0, max(score)*1.2)
)
Data:
score <- structure(c(96.8, 95.2, 100, 100, 89.7, 89.2, 81.4, 81, 85.1,
82), dim = c(2L, 5L), dimnames = list(c("1", "2"), c("A", "B",
"C", "D", "E")))
I have a table (below) showing the percentage of tree species (categorical variable) present in a group experiment. My objective is to plot the percentage of tree species on the y-axis and 'Species' on the x-axis within a barplot.
Issue
My problem is that I am experiencing problems with formatting the x-axis correctly. My objective is to ensure that the x-axis labels for**'Species'** are:-
Positioned directly underneath their bar at the tick mark
Do not overlap onto the plotting area
If anyone can help solve this issue, I would be incredibly grateful.
R code
df <- leaf.percent[order(leaf.percent$Leaf.Percentge, decreasing = TRUE),]
Tree.labels<-c("Quercus robar", "Quercus Patraea",
"Deciduous", "Oak",
"Plant", "Shrub")
par(mar=c(6, 6, 3, 3))
Tree<-barplot(df$Leaf.Percentge, names.arg = df$Species,
xaxt = "n",
ylab="Percentage %",
xlab="Tree Species",
col="lightblue",
ylim = c(0, 60))
axis(1, at=Tree, labels=FALSE)
text(seq(1, 6, by=1), par("usr")[3] - 0.2,
labels=unique(Tree.labels),
srt = 25, pos = 1,
xpd = TRUE, cex=0.7)
DATA
structure(list(Species = structure(1:6, .Label = c("Deciduous",
"Oak", "Plant", "Quercus_petraea", "Quercus_robur", "Shrub"), class = "factor"),
Frequency = c(48L, 29L, 6L, 70L, 206L, 4L), Leaf.Percentge = c(13.2231404958678,
7.98898071625344, 1.65289256198347, 19.2837465564738, 56.7493112947658,
1.10192837465565)), .Names = c("Species", "Frequency", "Leaf.Percentge"
), row.names = c(NA, -6L), class = "data.frame")
x<- structure(list(count = c(4259120, 4317840, 4444000, 4254240,
4656800), the_date = structure(c(1389589200, 1389675600, 1389762000,
1389848400, 1389934800), class = c("POSIXct", "POSIXt"), tzone = "")), .Names = c("count",
"the_date"), row.names = c(51L, 406L, 664L, 197L, 196L), class = "data.frame")
par(mar = c(8, 4, 4, 2) + 0.1)
plot(x$the_date, x$count, type="l", xaxt = "n", xlab = "")
axis(1, labels = FALSE)
labels<-x$the_date
labels<-format(labels, format="%b-%d-%Y")
text(x$the_date, par("usr")[3] - 0.75, srt = 55, adj = 1, labels = labels, xpd = TRUE)
I've tried adjusting the par("usr")[3] - 0.75 offset as specified here, but the labels aren't moving at all.
You can a trick like this using 2 calls to axis functions. I am using here axis.Date since you deal with dates(better for formatting). Then you can ply with line argument t play with labels positions.
axis(1,labels=FALSE)
axis.Date(1,at = x$the_date,las=2, format= "%m-%d",line=0.5,tick=FALSE)
Such as margins, orientations and such...
dev.off() does not work for me. I am often using RStudio, with its inbuilt graphics device. I then have plotting functions, which I want to plot either in the default RStudio graphics device, or if I called X11(), before in a new window.
This behaviour doesn't work with dev.off(). If my plotting function always calls dev.off(), it might inadvertently close the X11() window and instead plot in the RStudio device. If I always call dev.off() followed by X11(), it would always plot in a new window, even if I wanted to plot in the RStudio device.
Ordinarily that could be solved with getOption("device"), however, that always returns RStudioGD.
See ?par. The idea is that you save them as they are when you found them, and then restore:
old.par <- par(mar = c(0, 0, 0, 0))
## do plotting stuff with new settings
Now restore as they were before we changed mar:
par(old.par)
In RStudio, You can just navigate to 'Plots' and select 'Remove plots'
If you already missed saving the default parameters at startup, and you don't want to restart the session, then you can open a terminal and run R by (usually) typing R.
Then type:
par()
It will print all the default values.
You can save them in a text file and import into the workspace that you are currently working in.
a simple function containing all the defaults can do the job:
reset_par <- function(){
op <- structure(list(xlog = FALSE, ylog = FALSE, adj = 0.5, ann = TRUE,
ask = FALSE, bg = "transparent", bty = "o", cex = 1,
cex.axis = 1, cex.lab = 1, cex.main = 1.2, cex.sub = 1,
col = "black", col.axis = "black", col.lab = "black",
col.main = "black", col.sub = "black", crt = 0, err = 0L,
family = "", fg = "black", fig = c(0, 1, 0, 1),
fin = c(6.99999895833333, 6.99999895833333), font = 1L,
font.axis = 1L, font.lab = 1L, font.main = 2L,
font.sub = 1L, lab = c(5L, 5L, 7L), las = 0L,
lend = "round", lheight = 1, ljoin = "round", lmitre = 10,
lty = "solid", lwd = 1, mai = c(1.02, 0.82, 0.82, 0.42),
mar = c(5.1, 4.1, 4.1, 2.1), mex = 1, mfcol = c(1L, 1L),
mfg = c(1L, 1L, 1L,1L), mfrow = c(1L, 1L),
mgp = c(3, 1, 0), mkh = 0.001, new = FALSE,
oma = c(0, 0, 0, 0), omd = c(0, 1, 0, 1),
omi = c(0, 0, 0,0), pch = 1L,
pin = c(5.75999895833333, 5.15999895833333),
plt = c(0.117142874574832, 0.939999991071427,
0.145714307397962, 0.882857125425167),
ps = 12L, pty = "m", smo = 1, srt = 0, tck = NA_real_,
tcl = -0.5, usr = c(0.568, 1.432, 0.568, 1.432),
xaxp = c(0.6, 1.4, 4), xaxs = "r", xaxt = "s",
xpd = FALSE, yaxp = c(0.6, 1.4, 4), yaxs = "r",
yaxt = "s", ylbias = 0.2),
.Names = c("xlog", "ylog", "adj", "ann", "ask", "bg",
"bty", "cex", "cex.axis", "cex.lab", "cex.main", "cex.sub",
"col", "col.axis", "col.lab", "col.main", "col.sub", "crt",
"err", "family", "fg", "fig", "fin", "font", "font.axis",
"font.lab", "font.main", "font.sub", "lab", "las", "lend",
"lheight", "ljoin", "lmitre", "lty", "lwd", "mai", "mar",
"mex", "mfcol", "mfg", "mfrow", "mgp", "mkh", "new", "oma",
"omd", "omi", "pch", "pin", "plt", "ps", "pty", "smo",
"srt", "tck", "tcl", "usr", "xaxp", "xaxs", "xaxt", "xpd",
"yaxp", "yaxs", "yaxt", "ylbias"))
par(op)
}
call it using:
reset_par()
The canonical answer was only in a comment (by Cookie), and might easily be overlooked:
Get the current/default parameters
old.par <- par(no.readonly = TRUE)
Set them in your code, e.g.
par(mai=c(0,0,0,0))
And then you can reset the pars with
par(old.par)
Or, in a function
on.exit(par(old.par))
For margins ?par provides a default value of c(5,4,4,2)+0.1. The following should reset the margins to the default values.
par(mar=c(5,4,4,2)+0.1)