How can I make legend next to my piechart in R? - r

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.

Related

adjusting y-axis scale and x-axis on side by side barchart

I used the following code to produce a side-by-side bar chart
IT=c(0.588, 0.765)
GE=c(0.214, 0.63)
FR=c(0.316, 0.356)
PO=c(0.692,0.793)
UK=c(0.381, 0.757)
NE=c(0.227, 0.62)
GR=c(0.692, 0.902)
HU=c(0.706, 0.698)
SW=c(0.143, 0.493)
# combine two vectors using cbind
# function
CountryChart=cbind(IT,GE,FR,PO,UK,NE,GR,HU,SW)
# pass this college_data to the
# barplot
barplot(CountryChart,beside=T)
and it produce a graph with the correct data, however the y-axis is too short as it only goes from 0 to 0.8 and not to 1.
The country labels are also not all displayed on the x-axis. Only four country codes are displayed so I would like to adjust the code so that it would display the code of each country below its bars.
Here's the graph I was able to produce:
Any idea on what to do to adjust the scale size of y-axis and display all country codes on the x-axis?
To get the y axis to go to 1, add ylim = c(0, 1) in the barplot call:
barplot(CountryChart,beside=T, ylim = c(0, 1))
To make all your countries appear on the x axis, you need to realise that the plot is suppressing some of the labels to prevent them from overlapping. To fix this, you can shrink the x label sizes:
barplot(CountryChart,beside=T, ylim = c(0, 1), cex.names = 0.75)
Or simply drag your plotting window to make it wider:
barplot(CountryChart,beside=T, ylim = c(0, 1))

Place bars at specific x-axis values in a barplot

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)

R Plotting Series of Data with Secondary axis

I would like to plot a data frame with 4 columns:
Quarters <- c("Q1","Q2","Q3")
Series1 <- c("1%","2%","3%")
Series2 <- c("4%","5%","6%")
Series3 <- c("1000","2000","3000")
df <- data.frame(Quarters,Series1,Series2,Series3)
Quarters as x-axis, Series1 & Series2 as left y-axis, Series3 as right y-axis and a legend.
I have seen some solutions with ggplot using scale_y_continues, but then the secondary (y) axis has to be a multiple of the primary axis. Which I do not want, as the data will be dynamic and the ratio might not hold through in all instances.
Any solutions how I might go about creating this? Perhaps ggplot is not the way to go?
I don't know about ggplot2, but you can use par(new = T) in R to plot a graph on top of another one.
If you remove the right axis from the first plot and add it manually on the second one it should look good.
Quarters <- c(1,2,3)
Series1 <- c(0.01,0.02,0.03)
Series2 <- c(0.04,0.05,0.06)
Series3 <- c(1000,2000,3000)
par(mar = c(5,5,2,5)) # Leaves some space for the second axis
plot(Quarters,Series1,type="l",ylim=c(0,0.1))
lines(Quarters,Series2,col="red")
par(new=T)
plot(Quarters,Series3,type="l",axes=F, xlab=NA, ylab=NA,col="blue") # Removes axis and labels so they don't overlap
axis(side = 4) # Adds secondary axis
Does this work for you? More info here
ggplot2 is perfectly fine and deals with dual-axis very well. You would use sec.axis within scale_y_continuous or scale_y_discrete (or really just about any valid scale_y_) call:
scale_y_continuous(
"Casualties* due to:",
sec.axis = sec_axis(~. *0.001,
name="Aircraft passengers carried, bn",
labels = scaleFUN,
breaks = seq(0,3, by=0.5)),
limits = c(0,3000),
breaks = seq(0,3000, by=500),
labels = comma
)
The following creates two axis, one with a break of 0 to 3000, by 500. That's the axis on the left (primary axis). The second one goes by 0 to 3 by 0.5, but there's no reason why it should follow that scale. You can very well have scales that are not multiples of the primary axis.
You can get a plot like the following:
Using the above technique. If it is helpful I put up the full ggplot code to recreate the above plot in this post. Completely done in ggplot2 including the horizontal legend and secondary axis.
Good luck!

Segmenting X-axis label in an R plot

I've been working extensively with R lately and I have a nitpicky plotting question.
I've attached an image of my current plot as reference. As you can see, I've added vertical lines to segment parts of my data inputs. I have 200 'agents' and each of them comes from different categorical subsets which make them all a little different. So, my goal is to keep the bottom axis as the index of my 'agents' vector, but I'd like to add a label to each of my subdivisions at the bottom to make it a little clearer as to why I'm segmenting them with the vertical lines.
Any suggestions?
http://i.imgur.com/YGNdBhg.png?1?1971
You just need to call axis like this:
x = sin(1:100) + rnorm(100, 0,.125)
breaks = c(10,33,85, 96)
plot(x)
sapply(breaks, function(x){abline(v=x, lty=2)})
axis(1, breaks, as.character(breaks))
If you don't want the default ticks plotted at all (i.e. just the ticks in the "breaks" vector) you just need to modify this slightly:
plot(x, axes=F)
sapply(breaks, function(x){abline(v=x, lty=2)})
axis(1, breaks, as.character(breaks))
axis(2)
box()
You don't provide any example data or code, so the code I am sending is untested. I am calling the vector of vertical lines vertlines and the vector of labels labels. I define the midpoints of each category using the vertlines and the range of the agent values. Then I add them to the plot using the mtext() function. Give it a try.
vertlines <- c(40, 80, 120, 140, 160, 180)
labels <- letters[1:7]
labelx <- diff(c(1, vertlines, 200))/2 + c(1, vertlines)
mtext(labels, at=labelx, side=1, line=4)

How to combine a plot and legend?

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.

Resources