This question already has answers here:
Easily add an '(all)' facet to facet_wrap in ggplot2?
(3 answers)
Closed 5 years ago.
It is often the case that we produce facets to decompose the data according to a variable, but that we still would like to see a summary as a stack of the facets. Here is an example:
library(ggplot2)
ggplot(data=iris, aes(x=Sepal.Length,y=Petal.Length)) +
geom_point(aes(color=Species)) +
facet_wrap(~Species, ncol=2)
However, I would also like that one of the facets is the overlay of the 3 facets:
ggplot(data=iris, aes(x=Sepal.Length,y=Petal.Length)) +
geom_point(aes(color=Species))
Is there anyway of doing this easily?
Many thanks,
I wrote the following function to duplicate the dataset and create an extra copy under of the data under variable all.
library(ggplot2)
# Create an additional set of data
CreateAllFacet <- function(df, col){
df$facet <- df[[col]]
temp <- df
temp$facet <- "all"
return(rbind(temp, df))
}
Instead of overwriting the original facet data column, the function creates a new column called facet. The benefit of this is that we can use the original column to specify the aesthetics of the plot point.
df <- CreateAllFacet(iris, "Species")
ggplot(data=df, aes(x=Sepal.Length,y=Petal.Length)) +
geom_point(aes(color=Species)) +
facet_wrap(~facet, ncol=2)
I feel the legend is optional in this case, as it largely duplicates information already available within the plot. It can easily be hidden with the extra line + theme(legend.position = "none")
Related
This question already has answers here:
wrapping long geom_text labels
(2 answers)
Closed 1 year ago.
I am trying to find a way to wrap geom_text/geom_label on a scatterplot (ggplot). I have seen ways this can be done manually inputting the co-ordinates - but i will have 10-20 variables, so this will not be possible.
I have a data frame that looks like this...
df <- data.frame(x =c(2,4,6,8),
y =c(7,3,5,4),
label =c("this variable has a long name which needs to be shortened",
"this variable has an even longer name that really needs to be shortened",
"this variables has a name that is much longer than two of the other name, so really needs to be shortened",
"this is pretty long too"))
and i want to make the following plot (but with wrapped labels)
ggplot(df, aes(x=x, y=y, label=label))+
geom_point()+
geom_text(nudge_y=0.05)+
xlim(0,10)+
theme_minimal()+
ggtitle("title")
This is the plot:
Have you tried str_wrap ? You might need to play around with width argument and nudge_y according to your actual data.
library(ggplot2)
df$label <- stringr::str_wrap(df$label, 25)
ggplot(df, aes(x=x, y=y, label=label))+
geom_point()+
geom_text(nudge_y=0.5)+
xlim(0,10)+
theme_minimal()+
ggtitle("title")
This question already has answers here:
How can I remove empty factors from ggplot2 facets?
(2 answers)
Closed 4 years ago.
I need to display a faceted bar plot for the count of levels in all the columns of the dataset.
the code,
aas <- sapply(AAA, is.factor)
aas1 <- AAA[,aas]
overview of aas1 dataset
aas2 <- data.frame(t(aas1))
aas2 <- cbind(names = rownames(aas2), aas2)
library(reshape2)
aas3 <- melt(aas2,id = "names")
aas3$variable <- 1
aas3$value <- as.factor(aas3$value)
aas4 <- aggregate(.~ names + value, aas3, sum)
overview of aas4 dataset
ggplot(aas4, aes(x=factor(value), y= variable)) +
geom_bar(stat="identity") + facet_grid(.~names) +
scale_fill_discrete(name="value") + xlab("")
facet bar plot
when i use aas4 dataset for faceted bar plot, each facet is consisting of all levels of "value", but i only need facets with levels corresponding to the variable "names"
Please suggest any better way to plot counts of levels of all factor variables in the dataset.
You need to specify that you want scales="free_x" and, in order not to have the same space for each facet, space="free".
+ facet_grid(.~names, scales="free_x", space="free_x")
I have 2 datasets, with different size. How do I simply plot them and have each with a different color and a legend?
So in this case, the legend would be count1, count2, and the legend title is something I choose, let's say: mylegend. What do I need to change or add to the following commands?
x <- data.frame(Q=1:10, count1=21:30)
y <- data.frame(Q=seq(1,10,0.5), count2=seq(11,20, 0.5))
ggplot() + geom_line(data=x, aes(x=Q, y=count1)) + geom_point(data=y, aes(x=Q, y=count2))
The easiest solution is to combine your data in the same data.frame, then set the aesthetics (aes) in ggplot.
Here is one way you can combine everything:
df <- data.frame(Q = c(x$Q, y$Q),
count = c(x$count1, y$count2),
type = c(rep("count1", 10), rep("count2", 19))
)
But you can also use commands like rbind() or melt() (from the reshape2 library).
With the data combined into one data.frame:
ggplot(df, aes(x=Q, y=count, colour=type)) + geom_point() + geom_line() +
scale_colour_discrete(name="mylegend")
This is a basic example, and I highly recommend Hadley Wickham's ggplot2 book, as well just searching google (Stack Overflow, R Cookbook, etc) for solutions to specific plotting problems or more ways to customize your plots.
This question already has answers here:
Is there an equivalent in ggplot to the varwidth option in plot?
(2 answers)
Closed 8 years ago.
I have a boxplot that I made in R with ggplot2 analagous to the sample boxplot below.
The problem is, for the values on the y axis (in this sample, the number of cylinders in the car) I have very different frequencies -- I may have included 2 8 cylinder cars, but 200 4 cylinder cars. Because of this, I'd like to be able to resize the boxplots (in this case, change the height along the y axis) so that the 4 cylinder boxplot is a larger portion of the chart than the 8 cylinder boxplot. Does someone know how to do this?
As #aosmith mentioned, varwidth is the argument you want. It looks like it may have been accidentally removed from ggplot2 at some point (https://github.com/hadley/ggplot2/blob/master/R/geom-boxplot.r). If you look at the commit title, it is adding back in the varwidth parmeter. I'm not sure if that ever made into the cran package, but you might want to check your version. It works with my version: ggplot2 v.1.0.0 I'm not sure how recently the feature was added.
Here is an example:
library(ggplot2)
set.seed(1234)
df <- data.frame(cond = factor( c(rep("A",200), rep("B",150), rep("C",200), rep("D",10)) ),
rating = c(rnorm(200),rnorm(150, mean=0.2), rnorm(200, mean=.8), rnorm(10, mean=0.6)))
head(df, 5)
tail(df, 5)
p <- ggplot(df, aes(x=cond, y=rating, fill=cond)) +
guides(fill=FALSE) + coord_flip()
p + geom_boxplot()
Gives:
p + geom_boxplot(varwidth=T)
Gives:
For a couple of more options, you can also use a violin plot with scaled widths (the scale="count" argument):
p+ geom_violin(scale="count")
Or combine violin and boxplots to maximize your information.
p+ geom_violin(scale="count") + geom_boxplot(fill="white", width=0.2, alpha=0.3)
I would like to plot an INDIVIDUAL box plot for each unrelated column in a data frame. I thought I was on the right track with boxplot.matrix from the sfsmsic package, but it seems to do the same as boxplot(as.matrix(plotdata) which is to plot everything in a shared boxplot with a shared scale on the axis. I want (say) 5 individual plots.
I could do this by hand like:
par(mfrow=c(2,2))
boxplot(data$var1
boxplot(data$var2)
boxplot(data$var3)
boxplot(data$var4)
But there must be a way to use the data frame columns?
EDIT: I used iterations, see my answer.
You could use the reshape package to simplify things
data <- data.frame(v1=rnorm(100),v2=rnorm(100),v3=rnorm(100), v4=rnorm(100))
library(reshape)
meltData <- melt(data)
boxplot(data=meltData, value~variable)
or even then use ggplot2 package to make things nicer
library(ggplot2)
p <- ggplot(meltData, aes(factor(variable), value))
p + geom_boxplot() + facet_wrap(~variable, scale="free")
From ?boxplot we see that we have the option to pass multiple vectors of data as elements of a list, and we will get multiple boxplots, one for each vector in our list.
So all we need to do is convert the columns of our matrix to a list:
m <- matrix(1:25,5,5)
boxplot(x = as.list(as.data.frame(m)))
If you really want separate panels each with a single boxplot (although, frankly, I don't see why you would want to do that), I would instead turn to ggplot and faceting:
m1 <- melt(as.data.frame(m))
library(ggplot2)
ggplot(m1,aes(x = variable,y = value)) + facet_wrap(~variable) + geom_boxplot()
I used iteration to do this. I think perhaps I wasn't clear in the original question. Thanks for the responses none the less.
par(mfrow=c(2,5))
for (i in 1:length(plotdata)) {
boxplot(plotdata[,i], main=names(plotdata[i]), type="l")
}