I am trying to plot line graphs for and facet_wrap for each dataset. What I would love to have is in light grey, transparent or something, all datasets in the background.
df <- data.frame(id=rep(letters[1:5], each=10),
x=seq(10),
y=runif(50))
ggplot(df, aes(x,y, group=id)) +
geom_line() +
facet_wrap(~ id)
This graph is how far I get, but I would love to have all the other missing 4 lines in each graph as well... In any way I try to use facet_wrap, I get only the data of a single line.
What I would expect is something like this for each facet.
ggplot(df, aes(x,y, group=id)) +
geom_line() +
geom_line(data=df[1:10,], aes(x,y, group=id), size=5)
Here's another approach:
First add a new column identical to id:
df$id2 <- df$id
Then add another geom_line based on the df without the original id column:
ggplot(df, aes(x,y, group=id)) +
geom_line(data=df[,2:4], aes(x=x, y=y, group=id2), colour="grey") +
geom_line() +
facet_wrap(~ id)
Here is an approach. It might not be suitable for larger datasets, as we replicate the data number_of_facets-times.
First, we do some data-wrangling to create this desired dataframe.
df$obs_id <- 1:nrow(df) #unique ID for each observation
#new data with unique ID's and 'true' facets
df2 <- expand.grid(true_facet=unique(df$id), obs_id=1:nrow(df))
#merge them
dat <- merge(df,df2,by="obs_id",all=T)
Then, we create a flag defining the 'true' faceted variable, and to discern background from foreground.
dat$col_flag <- dat$true_facet == dat$id
Now, plotting is easy. I've used geom_line twice instead of scales, as that was easier than to try to fix the ordering (would lead to black being plotted below grey).
p1 <- ggplot(dat, aes(x=x,y=y, group=id))+
geom_line(color="grey")+
geom_line(dat=dat[dat$col_flag,],size=2,color="black")+
facet_wrap(~true_facet)
Related
My data is in the long format (as required to do the grouped barplot), so that the values for different categories are in one single column. The data is here.
Now, a standard barplot with ggplot2 orders the bars alphabetically (in my case of country names, from Argentina to Uganda). I want to keep the order of countries as it is in the dataframe. Using the suggestion here (i.e. ussing the limits= option inside the scale_x_discrete function) I get the following graph:
My code is this:
mydata <- read_excel("WDR2016Fig215.xls", col_names = TRUE)
y <- mydata$value
x <- mydata$country
z <- mydata$Skill
ggplot(data=mydata, aes(x=x, y=y, fill=z)) +
geom_bar(stat="identity", position=position_dodge(), colour="black") +
scale_x_discrete(limits=x)
The graph is nicely sorted as I want but the x axis is for some reason expanded. Any idea what is the problem?
this?
mydata$country <- factor(mydata$country, levels=unique(mydata$country)[1:30])
ggplot(data=mydata, aes(x=country, y=value, fill=Skill)) +
geom_bar(stat="identity", position=position_dodge(), colour="black")
I am trying to make a two facet line plot as this example. My problem is to arrange data to show desired variable on x-axis. Here is small data set I wanna use.
Study,Cat,Dim1,Dim2,Dim3,Dim4
Study1,PK,-3.00,0.99,-0.86,0.46
Study1,US,-4.67,0.76,1.01,0.45
Study2,FL,-2.856,4.15,1.554,0.765
Study2,FL,-8.668,5.907,3.795,4.754
I tried to use the following code to draw line graph from this data frame.
plot1 <- ggplot(data = dims, aes(x = Cat, y = Dim1, group = Study)) +
geom_line() +
geom_point() +
facet_wrap(~Study)
As is clear, I can only use one value column to draw lines. I want to put Dim1, Dim2, Dim3, Dim4 on x axis which I cannot do in this arrangement of data. [tried c(Dim1, Dim2, Dim3, Dim4) with no luck]
Probably the solution is to transpose the table but then I cannot reproduce categorization for facet (Study in above table) and colour (Cat in above table. Any ideas how to solve this issue?
You can try this:
library(tidyr)
library(dplyr)
gather(dims, variable, value, -Study, -Cat) %>%
ggplot(aes(x=variable, y=value, group=Cat, col=Cat)) +
geom_point() + geom_line() + facet_wrap(~Study)
The solution was quite easy. Just had to think a bit and the re-arranged data looks like this.
Study,Cat,Dim,Value
Study1,PK,Dim1,-3
Study1,PK,Dim2,0.99
Study1,PK,Dim3,-0.86
Study1,PK,Dim4,0.46
Study1,US,Dim1,-4.67
Study1,US,Dim2,0.76
Study1,US,Dim3,1.01
Study1,US,Dim4,0.45
Study2,FL,Dim1,-2.856
Study2,FL,Dim2,4.15
Study2,FL,Dim3,1.554
Study2,FL,Dim4,0.765
Study2,FL,Dim1,-8.668
Study2,FL,Dim2,5.907
Study2,FL,Dim3,3.795
Study2,FL,Dim4,4.754
After that R produced desire result with this code.
plot1 <- ggplot(data=dims, aes(x=Dim, y=Value, colour=Cat, group=Cat)) + geom_line()+ geom_point() + facet_wrap(~Study)
I have the following code and I want to draw two lines, both specified in the same data frame. However, I'm getting big coloured shadows, and I'm not able to figure out the cause. The data and the code look correct to me...
library('ggplot2')
library('reshape2')
df <- read.csv(url("http://smallchess.com/test.csv"), row.names=1)
melted = melt(df, id.vars='time')
p <- ggplot(data=melted, aes(x=time, y=value, group=variable, colour=variable)) + geom_line()
print(p)
The two variables show extremely oscillating values. So that each line overlaps its neighbor. Thus, this opaque structure is generated. Perhaps it helps if you set your size of the line to a low value like this:
p <- ggplot(data=melted, aes(x=time, y=value, group=variable, colour=variable)) +
geom_line(size = 0.05)
print(p)
I have data that plots over time with four different variables. I would like to combine them in one plot using facet_grid, where each variable gets its own sub-plot. The following code resembles my data and the way I'm presenting it:
require(ggplot2)
require(reshape2)
subm <- melt(economics, id='date', c('psavert','uempmed','unemploy'))
mcsm <- melt(data.frame(date=economics$date, q=quarters(economics$date)), id='date')
mcsm$value <- factor(mcsm$value)
ggplot(subm, aes(date, value, col=variable, group=1)) + geom_line() +
facet_grid(variable~., scale='free_y') +
geom_step(data=mcsm, aes(date, value)) +
scale_y_discrete(breaks=levels(mcsm$value))
If I leave out scale_y_discrete, R complains that I'm trying to combine discrete value with continuous scale. If I include scale_y_discreate my continuous series miss their scale.
Is there any neat way of solving this issue ie. getting all scales correct ? I also see that the legend is alphabetically sorted, can I change that so the legend is ordered in the same order as the sub-plots ?
Problem with your data is that that for data frame subm value is numeric (continuous) but for the mcsm value is factor (discrete). You can't use the same scale for numeric and continuous values and you get y values only for the last facet (discrete). Also it is not possible to use two scale_y...() functions in one plot.
My approach would be to make mcsm value as numeric (saved as value2) and then use them - it will plot quarters as 1,2,3 and 4. To solve the problem with legend, use scale_color_discrete() and provide breaks= in order you need.
mcsm$value2<-as.numeric(mcsm$value)
ggplot(subm, aes(date, value, col=variable, group=1)) + geom_line()+
facet_grid(variable~., scale='free_y') + geom_step(data=mcsm, aes(date, value2)) +
scale_color_discrete(breaks=c('psavert','uempmed','unemploy','q'))
UPDATE - solution using grobs
Another approach is to use grobs and library gridExtra to plot your data as separate plots.
First, save plot with all legends and data (code as above) as object p. Then with functions ggplot_build() and ggplot_gtable() save plot as grob object gp. Extract from gp only part that plots legend (saved as object gp.leg) - in this case is list element number 17.
library(gridExtra)
p<-ggplot(subm, aes(date, value, col=variable, group=1)) + geom_line()+
facet_grid(variable~., scale='free_y') + geom_step(data=mcsm, aes(date, value2)) +
scale_color_discrete(breaks=c('psavert','uempmed','unemploy','q'))
gp<-ggplot_gtable(ggplot_build(p))
gp.leg<-gp$grobs[[17]]
Make two new plot p1 and p2 - first plots data of subm and second only data of mcsm. Use scale_color_manual() to set colors the same as used for plot p. For the first plot remove x axis title, texts and ticks and with plot.margin= set lower margin to negative number. For the second plot change upper margin to negative number. faced_grid() should be used for both plots to get faceted look.
p1 <- ggplot(subm, aes(date, value, col=variable, group=1)) + geom_line()+
facet_grid(variable~., scale='free_y')+
theme(plot.margin = unit(c(0.5,0.5,-0.25,0.5), "lines"),
axis.text.x=element_blank(),
axis.title.x=element_blank(),
axis.ticks.x=element_blank())+
scale_color_manual(values=c("#F8766D","#00BFC4","#C77CFF"),guide="none")
p2 <- ggplot(data=mcsm, aes(date, value,group=1,col=variable)) + geom_step() +
facet_grid(variable~., scale='free_y')+
theme(plot.margin = unit(c(-0.25,0.5,0.5,0.5), "lines"))+ylab("")+
scale_color_manual(values="#7CAE00",guide="none")
Save both plots p1 and p2 as grob objects and then set for both plots the same widths.
gp1 <- ggplot_gtable(ggplot_build(p1))
gp2 <- ggplot_gtable(ggplot_build(p2))
maxWidth = grid::unit.pmax(gp1$widths[2:3],gp2$widths[2:3])
gp1$widths[2:3] <- as.list(maxWidth)
gp2$widths[2:3] <- as.list(maxWidth)
With functions grid.arrange() and arrangeGrob() arrange both plots and legend in one plot.
grid.arrange(arrangeGrob(arrangeGrob(gp1,gp2,heights=c(3/4,1/4),ncol=1),
gp.leg,widths=c(7/8,1/8),ncol=2))
I am trying to change the colours on a ggplot column chart. After googling, I thought that the following code would work:
require(ggplot2)
require(RColorBrewer)
State <- c(rep("NSWTC",5), rep("TCV",5), rep("QTC",5),
rep("WATC",5), rep("SAFA",5), rep("Other",5))
Year <- rep(c("11-12","12-13","13-14","14-15","15-16"),6)
##some random data
Funding.Programme <- abs(rnorm(30))
df <- data.frame(State, Year, Funding.Programme)
##this line makes the graph in the order you inputted it, rather than alphabetical
df$State <- factor(df$State, levels=unique(df$State))
##ugly coloured
bars <- ggplot(df) +
aes(x=Year ,y=Funding.Programme, fill=Year) +
geom_bar(stat='identity') +
facet_grid(facets=~State) +
scale_y_continuous('Gross Issuance Requirements')
##nicely coloured
blues <- brewer.pal(5, "Blues")
blues <- rev(blues)
##the following two graphs have the same colours
bars <- ggplot(df) +
aes(x=Year ,y=Funding.Programme, fill=Year) +
geom_bar(stat='identity') +
facet_grid(facets=~State) +
scale_y_continuous('Gross Issuance Requirements') +
scale_fill_brewer(blues)
bars
bars <- ggplot(df) +
aes(x=Year ,y=Funding.Programme, fill=Year) +
geom_bar(stat='identity') +
facet_grid(facets=~State) +
scale_y_continuous('Gross Issuance Requirements') +
scale_fill_brewer(blues.rev)
bars
##and this does not adjust the default colours
bars <- ggplot(df)+
aes(x=Year,y=Funding.Programme, fill=Year) +
geom_bar(stat='identity') +
facet_grid(facets=~State) +
scale_y_continuous('Gross Issuance Requirements') +
scale_colour_manual(values = blues.rev)
bars
But the last method does not work, and the second and third-last charts produced are identical, despite the order of colours being reversed in the object.
You want scale_fill_manual(values = blues) or conversely with blues.rev (which you didn't actually create in your example code, which I assume is a typo).
Only use scale_*_brewer when you're selecting one of the default palette's by name. Otherwise, use scale_*_manual for this sort of thing.
The last one doesn't work because you were using colour instead of fill.
Finally, carriage returns and tabs: love them, cherish them, use them!