How to change the order of facet.var from alphabetic in iNext function? - facet-wrap

I am trying to make a graph with multiple facets in iNext. Facets are months. Since the default is the alphabetic order, to make the panels of facet, it puts August, July, June, May. But I want the reverse order. I tried to make site (which is the month in my case) as a factor. But it did not work.
Anybody has an idea what I can do to fix this?

I've also wanted to know how the designers wanted us to do that. My workaround was to build it up from more basic parts... below you can see how I reordered by descending elevation in the ant dataset:
# faceting in iNEXT
library(iNEXT)
data(ant)
adat<-iNEXT(ant, datatype = "incidence_freq")
# if you look in Anne Chao's github, you can see the source code for ggiNEXT
# it generates a df with fortify.iNEXT, which is what ggiNEXT plots
plotdf<-fortify.iNEXT(adat, type=1)
#manually relevel the factor
plotdf$site<-factor(plotdf$site, levels=c("h2000m", "h1500m","h1070m", "h500m", "h50m"))
#then just use your own clever ggplot ideas to make the plot you want
p<-(plotdf %>% ggplot(aes(x,y, colour=order))
+ geom_point(size=1)
+ geom_line(lwd=0.5)
+ theme(legend.position = "none")
+ facet_wrap(~site)
+ theme_classic()
)
print(p)
https://github.com/AnneChao/iNEXT/blob/master/R/ggiNEXT.R

Related

Cannot get ggplot2 to show a trendline by month

I am trying to plot trendlines for my data by month and visualize them on a faceted ggplot. R is not allowing me to show the trendline. I want to use geom_line() or geom_smooth(). I have a hypothesis about why this is happening, I am assuming it's because ggplot is viewing the Month names as categorical (factors), seeing as my code otherwise seems to match online tutorials for showing points and lines on the same faceted ggplot.
I tried using month.name, to convert my month names to recognizable months to test my hypothesis, but R does this incorrectly (May, July, and September were converted to April, February, and June?).
I also have the plots mainly displaying as I want, for example yields the following:
Toledo_month_log_cyano %>% ggplot(aes(x=Month, y = `Log GC/L`)) +
geom_point(aes(color = gene)) +
geom_smooth() +
theme_classic() +
facet_wrap(~gene, ncol = 1)
It looks mainly how I want, I just want a trend line which doesn't show. If someone could help me figure out what the problem is and solve it that would be great!

colour single ggplot axis item

I have created a chart and am wanting to colour one of the x-axis items based on a variable. I have seen this post (How to get axis ticks labels with different colors within a single axis for a ggplot graph?), but am struggling to apply it to my dataset.
df1 <- data.frame(var=c("a","b","c","a","b","c","a","b","c"),
val=c(99,120,79,22,43,53,12,27,31),
type=c("alpha","alpha","alpha","bravo","bravo","bravo","charlie","charlie","charlie"))
myvar="a"
ggplot(df1,aes(x=reorder(var,-val), y=val,fill=type)) + geom_bar(stat="identity")
Any tips on how to make the x-axis value red when it is equal to myvar?
Update: Thanks to #ddiez for some guidance. I finally came around to the fact that i would have to reorder prior to plotting. I also should have made my original example with data.table, so am not sure if this would influenced original responses. I modified my original dataset to be a data.table and used the following code to achieve success.
df1 <- data.table(var=c("a","b","c","a","b","c","a","b","c"),
val=c(99,120,79,22,43,53,12,27,31),
type=c("alpha","alpha","alpha","bravo","bravo","bravo","charlie","charlie","charlie"))
myvar="a"
df1[,axisColour := ifelse(var==myvar,"red","black")]
df1$var <- reorder(df1$var,-df1$val,sum)
setkey(df1,var,type)
ggplot(df1,aes(x=var, y=val,fill=type)) + geom_bar(stat="identity") +
theme(axis.text.x = element_text(colour=df1[,axisColour[1],by=var][,V1]))
There may be a more elegant solution but a quick hack (requires you to know the final order) would be:
ggplot(df1,aes(x=reorder(var,-val), y=val,fill=type)) +
geom_bar(stat="identity") +
theme(axis.text.x = element_text(colour=c("black","black","red")))
A solution using the variable myvar (yet, there may be better ways):
# reorder the factors in the data.frame (instead of in situ).
df1$var=reorder(df1$var, -df1$val)
# create a vector of colors for each level.
mycol=rep("black", nlevels(df1$var))
names(mycol)=levels(df1$var)
# assign the desired ones a different color.
mycol[myvar]="red"
ggplot(df1,aes(x=var, y=val,fill=type)) +
geom_bar(stat="identity") +
theme(axis.text.x = element_text(colour=mycol))

Plot multiple histograms in one using ggplot2 in R

I am fairly new to R and ggplot2 and am having some trouble plotting multiple variables in the same histogram plot.
My data is already grouped and just needs to be plotted. The data is by week and I need to plot the number for each category (A, B, C and D).
Date A B C D
01-01-2011 11 0 11 1
08-01-2011 12 0 3 3
15-01-2011 9 0 2 6
I want the Dates as the x axis and the counts plotted as different colors according to a generic y axis.
I am able to plot just one of the categories at a time, but am not able to find an example like mine.
This is what I use to plot one category. I am pretty sure I need to use position="dodge" to plot multiple as I don't want it to be stacked.
ggplot(df, aes(x=Date, y=A)) + geom_histogram(stat="identity") +
labs(title = "Number in Category A") +
ylab("Number") +
xlab("Date") +
theme(axis.text.x = element_text(angle = 90))
Also, this gives me a histogram with spaces in between the bars. Is there any way to remove this? I tried spaces=0 as you would do when plotting bar graphs, but it didn't seem to work.
I read some previous questions similar to mine, but the data was in a different format and I couldn't adapt it to fit my data.
This is some of the help I looked at:
Creating a histogram with multiple data series using multhist in R
http://www.cookbook-r.com/Graphs/Plotting_distributions_%28ggplot2%29/
I'm also not quite sure what the bin width is. I think it is how the data should be spaced or grouped, which doesn't apply to my question since it is already grouped. Please advise me if I am wrong about this.
Any help would be appreciated.
Thanks in advance!
You're not really plotting histograms, you're just plotting a bar chart that looks kind of like a histogram. I personally think this is a good case for faceting:
library(ggplot2)
library(reshape2) # for melt()
melt_df <- melt(df)
head(melt_df) # so you can see it
ggplot(melt_df, aes(Date,value,fill=Date)) +
geom_bar() +
facet_wrap(~ variable)
However, I think in general, that changes over time are much better represented by a line chart:
ggplot(melt_df,aes(Date,value,group=variable,color=variable)) + geom_line()

selecting only some facets to print in facet_wrap, ggplot2

my question is very simple, but I have failed to solve it after many attempts. I just want to print some facets of a facetted plot (made with facet_wrap in ggplot2), and remove the ones I am no interested in.
I have facet_wrap with ggplot2, as follows:
#anomalies linear trends
an.trends <- ggplot()+
geom_smooth(method="lm", data=tndvilong.anomalies, aes(x=year, y=NDVIan, colour=TenureZone,
group=TenureZone))+
scale_color_manual(values=miscol) +
ggtitle("anomalies' trends")
#anomalies linear trends by VEG
an.trendsVEG <- an.trends + facet_wrap(~VEG,ncol=2)
print(an.trendsVEG)
And I get the plot as I expected (you can see it in te link below):
anomalies' trends by VEG
The question is: how do I get printed only the facest I am interested on?
I only want to print "CenKal_ShWoodl", "HlShl_ShDens", "NKal_ShWoodl", and "ThShl_ShDens"
Thanks
I suggest the easiest way to do that is to simply give ggplot() an appropriate subset. In this case:
facets <- c("CenKal_ShWoodl", "HlShl_ShDens", "NKal_ShWoodl", "ThShl_ShDens")
an.trends.sub <- ggplot(tndvilong.anomalies[tndvilong.anomalies$VEG %in% facets,])+
geom_smooth(method="lm" aes(x=year, y=NDVIan, colour=TenureZone,
group=TenureZone))+
scale_color_manual(values=miscol) +
ggtitle("anomalies' trends") +
facet_wrap(~VEG,ncol=2)
Obviously without your data I can't be sure this will give you what you want, but based on your description, it should work. I find that with ggplot, it is generally best to pass it the data you want plotted, rather than finding ways of changing the plot itself.

How can I make a legend in ggplot2 with one point entry and one line entry?

I am making a graph in ggplot2 consisting of a set of datapoints plotted as points, with the lines predicted by a fitted model overlaid. The general idea of the graph looks something like this:
names <- c(1,1,1,2,2,2,3,3,3)
xvals <- c(1:9)
yvals <- c(1,2,3,10,11,12,15,16,17)
pvals <- c(1.1,2.1,3.1,11,12,13,14,15,16)
ex_data <- data.frame(names,xvals,yvals,pvals)
ex_data$names <- factor(ex_data$names)
graph <- ggplot(data=ex_data, aes(x=xvals, y=yvals, color=names))
print(graph + geom_point() + geom_line(aes(x=xvals, y=pvals)))
As you can see, both the lines and the points are colored by a categorical variable ('names' in this case). I would like the legend to contain 2 entries: a dot labeled 'Data', and a line labeled 'Fitted' (to denote that the dots are real data and the lines are fits). However, I cannot seem to get this to work. The (awesome) guide here is great for formatting, but doesn't deal with the actual entries, while I have tried the technique here to no avail, i.e.
print(graph + scale_colour_manual("", values=c("green", "blue", "red"))
+ scale_shape_manual("", values=c(19,NA,NA))
+ scale_linetype_manual("",values=c(0,1,1)))
The main trouble is that, in my actual data, there are >200 different categories for 'names,' while I only want the 2 entries I mentioned above in the legend. Doing this with my actual data just produces a meaningless legend that runs off the page, because the legend is trying to be a key for the colors (of which I have way too many).
I'd appreciate any help!
I think this is close to what you want:
ggplot(ex_data, aes(x=xvals, group=names)) +
geom_point(aes(y=yvals, shape='data', linetype='data')) +
geom_line(aes(y=pvals, shape='fitted', linetype='fitted')) +
scale_shape_manual('', values=c(19, NA)) +
scale_linetype_manual('', values=c(0, 1))
The idea is that you specify two aesthetics (linetype and shape) for both lines and points, even though it makes no sense, say, for a point to have a linetype aesthetic. Then you manually map these "nonsense" aesthetics to "null" values (NA and 0 in this case), using a manual scale.
This has been answered already, but based on feedback I got to another question (How can I fix this strange behavior of legend in ggplot2?) this tweak may be helpful to others and may save you headaches (sorry couldn't put as a comment to the previous answer):
ggplot(ex_data, aes(x=xvals, group=names)) +
geom_point(aes(y=yvals, shape='data', linetype='data')) +
geom_line(aes(y=pvals, shape='fitted', linetype='fitted')) +
scale_shape_manual('', values=c('data'=19, 'fitted'=NA)) +
scale_linetype_manual('', values=c('data'=0, 'fitted'=1))

Resources