I'm trying to attach a legend to a plot in R.
I tried the following code ( taken from http://www.harding.edu/fmccown/r/ )
# Define cars vector with 5 values
cars <- c(1, 3, 6, 4, 9)
# Define some colors ideal for black & white print
colors <- c("white","grey70","grey90","grey50","black")
# Calculate the percentage for each day, rounded to one
# decimal place
car_labels <- round(cars/sum(cars) * 100, 1)
# Concatenate a '%' char after each value
car_labels <- paste(car_labels, "%", sep="")
# Create a pie chart with defined heading and custom colors
# and labels
pie(cars, main="Cars", col=colors, labels=car_labels,
cex=0.8)
# Create a legend at the right
legend(1.5, 0.5, c("Mon","Tue","Wed","Thu","Fri"), cex=0.8,
fill=colors)
However, this does not work really well. After the pie(cars, main="Cars", col=colors, labels=car_labels,cex=0.8) line , the plot is shown without a legend :-) .......Every example I see on the Internet seems to have the legend function after the plotting function so it seems very weird..............
When I try to execute the legend function I get
legend(1.5, 0.5, c("Mon","Tue","Wed","Thu","Fri"), cex=0.8,
+ fill=colors)
Error in strwidth(legend, units = "user", cex = cex) :
plot.new has not been called yet
You are off the coordinate system. Try this instead
# Create a legend at the right
legend("topleft", c("Mon","Tue","Wed","Thu","Fri"), cex=0.8, fill=colors)
which produces the chart below:
See the help page for legend for different placement options.
I think the position 1.5, 0.5 puts it off the page. Try
legend("right", c("Mon","Tue","Wed","Thu","Fri"), cex=0.8, fill=colors)
After the pie function it appears with no legend; the legend function adds the legend to the current plot.
PS. You may also consider other types of plots. Pie charts are notorious for being visually misleading.
Related
I would like to represent two-dimensional data as bars, placed over the x-axis values, but barplot() does not allow to control x-axis placement, and plot() does not draw bars:
x <- c(1, 2, 3, 5)
y <- 1:4
plot(x, y, type = "h")
barplot(y)
Click for an image illustrating the plot() and barplot() examples.
I understand that I can plot a histogram –
hist(rep(x, y), breaks = seq(min(x) - 0.5, max(x) + 0.5, 1))
Click for an image illustrating the hist() example.
– but the recreation of the original (non-frequency) data and the calculation of the breaks is not always as straightforward as in this example, so:
Is there a way to force plot() to draw bars?
Or is there a way to force barplot() to place the bars at specific values on the x-axis?
Basically, what I would like is something like:
barplot(y, at = x)
I would prefer to use base R and avoid ggplot.
While I agree with #Dave2e that a barplot may not be the best way to represent your data, you can get something like what you are describing by starting with a blank plot and drawing the relevant rectangles. I am using your y values (1:4) and the x values that you mentioned in your comment. I am not sure what you want on the x-axis, but I show labels for the x-values that you give. In order to look like a barplot, I suppress the tick marks on the x-axis.
plot(NULL, xlim=c(0,11), ylim=c(0,4.5), bty="n",
xaxt="n", xaxs="i", yaxs="i", xlab="", ylab="")
rect(x-0.5, 0, x+0.5, y, col="gray")
axis(side=1, at=x, col.ticks=NA)
I have made a piechart in R with the next code:
#make slices
slices <- c(19, 26, 55)
# Define some colors
colors <- c("yellow2","olivedrab3","orangered3")
# Calculate the percentage for each day, rounded to one decimal place
slices_labels <- round(slices/sum(slices) * 100, 1)
# Concatenate a '%' char after each value
slices_labels <- paste(slices_labels, "%", sep="")
# Create a pie chart with defined heading and custom colors and labels
pie(slices, main="Sum", col=colors, labels=slices_labels, cex=0.8)
# Create a legend at the right
legend("topright", c("DH","UT","AM"), cex=0.7, fill=colors)
But I want the legend next to my piechart. I have also tried the following code: legend("centreright", c("DH","UT","AM"), cex=0.7, fill=colors).
But this does not give me a legend next to my pie chart.
Which code do I have to use to make a legend next to my pie chart in the middle?
You can play with the x and y argument from legend (cf ?legend):
legend(.9, .1, c("DH","UT","AM"), cex = 0.7, fill = colors)
However, a pie chart may not be the best way to represent your data, because our eye is not very good in assessing angles. The only usecase where a pie chart seems reasonable to me is when comparing 2 categories, because due to watches we can assess these proportions rather easily.
I have created a scatter plot with circle size changing with the intensity of the data: Fro 0 to 2, from 2 to 4,.. from 8 to 10. Does anyone could help me to create the proper legend for my plot?.
My code is:
require(xlsx)
data <- read.xlsx("data.xlsx", 1, header=TRUE) # reading the data
BRfunc <- colorRampPalette(c("blue", "red")) # the color gradient
itvl <- c(0,2,4,6,8,10)
plot(data$years, data$cars, cex=findInterval(data$emission, itvl), col="black" )
I've created a reproducible data set
n <- 50
data <- data.frame(years=1950+(1:n), cars=rnorm(n), emission=runif(n,0,10))
Then use your code to plot the figure
itvl <- c(0,2,4,6,8,10)
plot(data$years, data$cars, cex=findInterval(data$emission, itvl), col="black" )
To be able to create the legend, I've used legend() as Marc in the box suggested.
legend("topright", legend=itvl, pt.cex=itvl, pch=1)
You can use options such as xjust and x.intersp to change the spacing between the symbols and legend. You can use bty to remove the box.
I have a series of plots that I want on a single page. I first use the command layout to specify my plot layout:
layout(matrix(c(1,1,2,2,1,1,2,2,3,4,5,6),3,4,byrow=TRUE))
For plot 1, I have something like:
plot(Easting,Northing, pch=16, col=grey(cex.size)) #The cex.size colours my dots according to some value
I now want to draw an inset plot on plot 1, but not move to plot 2 yet.
I tried following the code :
par(fig=c(0.75, 1, 0, 0.25), new = T)
plot(spp.tmp[,1:2], col=cols[spp.tmp[,3]+1], pch=16)
par(fig=c(0,1,0,1))
But this doesnt work, as par(fig()) command overwrites my layout, and the inset plot appears on the bottom corner of my overall figure, not just in the bottom corner of plot 1.
Two options,
You coul try and include the inset within your layout command (if you were to stick with layout
Here is a case where the first plot spans two rows and column, the second is an inset in the bottom right corner of the first. The third plot is below, the same size as the first, but without an inset.
layout( matrix(c(1,1,1,2,3,3,3,3), 4, 2, byrow = TRUE) )
## show the regions that have been allocated to each plot
layout.show(3)
An alternative is to use subplot from the TeachingDemos package
library(TeachingDemos)
layout(matrix(c(1,1,0,2),2,2,TRUE))
plot(1)
subplot(plot(1), x = c(1.2),y=0.8)
plot(2)
This is my hatchet approach using base graphics. Because your messing around with par(), why dont you change around the order in matrix and plot the tricky one last. This way the par settings do not affect any more plots in your layout, if you were to plot the tricky one first. It seems simplistic in this example, but when you have lots of plots and you want an inset in only 1, it works.
##generate some data
x<-rnorm(50)
y<-rnorm(50)
##set the layout
##so your first plot is plotted last
layout(matrix(c(2,2,0,1), 2,2, byrow=T))
#plot 1 is on the bottom right
plot(x,y, col="grey30", xlab="", ylab="")
#plot 2 is across the top
plot(x,y, col="grey30", xlab="", ylab="")
##set par to place the next plot in the existing plotting area
## and use fig to position it
par(fig=c(.65, .95, .55, .85), new = TRUE)
#inset 3rd plot int top plot, this effectively gives you a blank plot to populate
plot(x,y, col="white", xlab="", ylab="")
#and make the background white
rect(par("usr")[1],par("usr")[3],par("usr")[2],par("usr")[4],col = "white")
##then just add your points afterwards
points(x,y,col="tomato")
Hello I am trying to create a stacked barplot using the following code:
test <- as.matrix(read.csv(file="test4.csv",sep=",",head=TRUE))
test <- test[,2:ncol(test)]
pdf(file="test.pdf", height=4, width=6)
par(lwd = 0.3)
barplot(test, space=0.4, xaxt='n', ann=FALSE)
axis(1, cex.axis=0.25, las=2, at=1:ncol(test), space=0.4, labels=colnames(test))
dev.off()
And I get:
As you can see the labels in the x-axis do not match the bars in the plot. Also, the ticks are huge.
Can you guys help me beautify the x axis? Thanks so much
Try storing the returned value of the call to barplot() in a named object, and then passing that in to the at= argument of axis():
xLabLocs <- barplot(test, space=0.4, xaxt='n', ann=FALSE)
axis(1, cex.axis=0.25, las=2, at=xLabLocs,
space=0.4, labels=colnames(test))
This may look odd, but it is explained in the Value section of the ?barplot help file:
Value:
A numeric vector (or matrix, when ‘beside = TRUE’), say ‘mp’,
giving the coordinates of _all_ the bar midpoints drawn, useful
for adding to the graph.
You just made the (easy enough to make) mistake of assuming that the x-axis coordinates of the bar centers are at 1:n, where n is the number of bars. That's not necessarily true, so it's nice that a single call to barplot() will both: (a) plot the bar plot as its side effect; and (b) return the necessary x-axis coordinates as its return value.