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
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))
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 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!
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)
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.