Plot line graphs with with a factor variable on x-axis - r

I failed to plot a line graph on x axis using initials of months with this code:
yrange<-range(c(Estimate, lcl,ucl))
plot(nmonth, Estimate, type = "b", pch = 20, ylim = yrange,
xlab = "Months", ylab = expression(hat(beta) * " estimates" * " & " * " confidence " * " levels "))
lines(nmonth, ucl, lty = 2)
lines(nmonth, lcl, lty = 2)
abline(h = 0, lty = 3)
and with this as well.
ggplot(data=df1, aes(x=nmonth, y=Estimate)) + geom_line() + geom_point() + geom_line(size=0.1) + geom_line(aes(y = ucl)) + geom_line(aes(y = lcl))
Using numeric month(nmonth) I can produce a plot, but labels are not what I wished to have.
How can I plot with all initials of the months on x axis?
The data is this one:
structure(list(Estimate = c(0.00571942142644563, 0.0111649330056159,
0.0143761435860972, 0.00739757934210567, 0.00110764672100624,
0.00168566337236168, 0.00392476757483504, 0.00234423892025447,
0.000166724737089459, -0.0014580012873366, -0.00197786373686253,
-0.00216289530501664), se = c(0.004018593736177, 0.0040534199847734,
0.0041113846550833, 0.00402501059422328, 0.00393358629717884,
0.00370406599461686, 0.003796651550619, 0.00392460643968604,
0.00376380927915926, 0.00391408378704714, 0.00388845564349082,
0.00394365265230613), nmonth = 1:12, month = structure(c(1L,
2L, 3L, 4L, 3L, 1L, 1L, 4L, 5L, 6L, 7L, 8L), .Label = c("J",
"F", "M", "A", "S", "O", "N", "D"), class = "factor"), lcl = c(-0.00215702229646129,
0.00322022983546004, 0.00631782966213393, -0.000491441422571959,
-0.00660218242146429, -0.00557430597708737, -0.0035166694643782,
-0.00534798970153017, -0.00721034145006269, -0.00912960550994899,
-0.00959923679810454, -0.00989245450353666), ucl = c(0.0135958651493525,
0.0191096361757718, 0.0224344575100605, 0.0152866001067833, 0.00881747586347677,
0.00894563272181073, 0.0113662046140483, 0.0100364675420391,
0.00754379092424161, 0.00621360293527579, 0.00564350932437948,
0.00556666389350337)), .Names = c("Estimate", "se", "nmonth",
"month", "lcl", "ucl"), class = "data.frame", row.names = c(NA,
-12L))

With ggplot2, it is easier if you first melt your data this way :
df <- melt(df, id.vars=c("month","nmonth"))
Then you can directly do :
ggplot(data=df, aes(x=month, y=value, group=variable)) + geom_line(aes(color=variable))
Note that the graph is not correct because you are using only the first letter of your months names.

Related

How to plot a combined bar and line plot in ggplot2

I have the following data which I am trying to plot as combined bar and line plot (with CI)
A data frame of Feature, Count, Odds Ratio and Confidence Interval values for OR
I am trying to get a plot as
A bar plot for count over lapped with a line plot for Odds Ratio with CI bars
I tried to plot in ggplot2 using following code:
ggplot(feat)+
geom_bar(aes(x=Feat, y=Count),stat="identity", fill = "steelblue") +
geom_line(aes(x=Feat, y=OR*max(feat$Count)),stat="identity", group = 1) +
geom_point(aes(x=Feat, y=OR*max(feat$Count))) +
geom_errorbar(aes(x=Feat, ymin=CI1, ymax=CI2), width=.1, colour="orange",
position = position_dodge(0.05))
However, I am not getting the CI bars for the line graph, as can be seen in pic: Rather, I am getting them for barplot
Can someone can please help me out to sort this issue.
Thanks
Edit - Dput:
df <- structure(list(Feat = structure(1:8, .Label = c("A", "B", "C",
"D", "E", "F", "G", "H"), class = "factor"), Count = structure(c(2L,
8L, 7L, 5L, 4L, 1L, 6L, 3L), .Label = c("13", "145", "2", "25",
"26", "3", "37", "43"), class = "factor"), OR = structure(c(4L,
2L, 1L, 5L, 3L, 7L, 6L, 8L), .Label = c("0.38", "1.24", "1.33",
"1.51", "1.91", "2.08", "2.27", "3.58"), class = "factor"), CI1 = structure(c(7L,
4L, 1L, 6L, 3L, 5L, 2L, 2L), .Label = c("0.26", "0.43", "0.85",
"0.89", "1.2", "1.24", "1.25"), class = "factor"), CI2 = structure(c(3L,
2L, 1L, 6L, 4L, 7L, 8L, 5L), .Label = c("0.53", "1.7", "1.82",
"1.98", "13.07", "2.83", "3.92", "6.13"), class = "factor")), class = "data.frame", row.names = c(NA,
-8L))
Is this what you had in mind?
ratio <- max(feat$Count)/max(feat$CI2)
ggplot(feat) +
geom_bar(aes(x=Feat, y=Count),stat="identity", fill = "steelblue") +
geom_line(aes(x=Feat, y=OR*ratio),stat="identity", group = 1) +
geom_point(aes(x=Feat, y=OR*ratio)) +
geom_errorbar(aes(x=Feat, ymin=CI1*ratio, ymax=CI2*ratio), width=.1, colour="orange",
position = position_dodge(0.05)) +
scale_y_continuous("Count", sec.axis = sec_axis(~ . / ratio, name = "Odds Ratio"))
Edit: Just for fun with the legend too.
ggplot(feat) +
geom_bar(aes(x=Feat, y=Count, fill = "Count"),stat="identity") + scale_fill_manual(values="steelblue") +
geom_line(aes(x=Feat, y=OR*ratio, color = "Odds Ratio"),stat="identity", group = 1) + scale_color_manual(values="orange") +
geom_point(aes(x=Feat, y=OR*ratio)) +
geom_errorbar(aes(x=Feat, ymin=CI1*ratio, ymax=CI2*ratio), width=.1, colour="orange",
position = position_dodge(0.05)) +
scale_y_continuous("Count", sec.axis = sec_axis(~ . / ratio, name = "Odds Ratio")) +
theme(legend.key=element_blank(), legend.title=element_blank(), legend.box="horizontal",legend.position = "bottom")
Since you asked about adding p values for comparisons in the comments, here is a way you can do that. Unfortunately, because you don't really want to add **all* the comparisons, there's a little bit of hard coding to do.
library(ggplot2)
library(ggsignif)
ggplot(feat,aes(x=Feat, y=Count)) +
geom_bar(aes(fill = "Count"),stat="identity") + scale_fill_manual(values="steelblue") +
geom_line(aes(x=Feat, y=OR*ratio, color = "Odds Ratio"),stat="identity", group = 1) + scale_color_manual(values="orange") +
geom_point(aes(x=Feat, y=OR*ratio)) +
geom_errorbar(aes(x=Feat, ymin=CI1*ratio, ymax=CI2*ratio), width=.1, colour="orange",
position = position_dodge(0.05)) +
scale_y_continuous("Count", sec.axis = sec_axis(~ . / ratio, name = "Odds Ratio")) +
theme(legend.key=element_blank(), legend.title=element_blank(), legend.box="horizontal",legend.position = "bottom") +
geom_signif(comparisons = list(c("A","H"),c("B","F"),c("D","E")),
y_position = c(150,60,40),
annotation = c("***","***","n.s."))

How to change linetype conditional on x-axis factor in ggplot when using geom_smooth?

Suppose I have a LOESS regression plot where the x-axis correspond to a categorical variable:
library(ggplot2)
b <- structure(list(Expression = c(16.201081535896, 16.5138880401065,
16.4244615700828, 1.62923743262849, 3.35379087562868, 6.99935683212696,
4.81932543877313, 3.85300704208448, 7.32436891427261, 4.23627699164079,
6.95731601433845, 4.33315521361287, 5.50596153247422, 13.0788494583573,
13.6909487566244, 12.9520674350314), stage = structure(c(1L,
1L, 1L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 4L, 4L, 4L, 5L, 5L, 5L), .Label = c("A",
"B", "C", "D", "E"), class = "factor")), row.names = c(NA, 16L
), class = "data.frame")
ggplot(b, aes(as.numeric(stage), Expression)) +
geom_point() +
geom_smooth(span = 0.8) +
scale_x_continuous(breaks = as.numeric(b$stage), labels = b$stage, minor_breaks = NULL)
I want to use 2 different line types at different sections of a LOESS regression.
Specifically, I would like to have a dashed line between A and B, a continuous line between B and D, and a dashed line again between D and E.
So I follow the example in:
conditional plot linetype in ggplot2
But the connection in the left and right are lost, and only the central part of the loess regression remains.
line.groups <- plyr::mapvalues(b$stage,
from = c("A", "B", "C", "D", "E"),
to = c(0, 1, 1, 1, 2))
ggplot(b, aes(as.numeric(stage), Expression)) +
geom_point() +
geom_smooth(aes(group=line.groups, linetype=line.groups), span = 0.8) +
scale_linetype_manual(values=c(2,1,2)) +
guides(linetype=FALSE) +
scale_x_continuous(breaks = as.numeric(b$stage), labels = b$stage, minor_breaks = NULL)
Is there a way to change the linetype of the geom_smooth ggplot, conditional to the x-axis (where x is a factor)?
EDIT:
I tried using three separate calls to geom_smooth for each section as suggested by a comment, but the standard error bounds won't be "smooth" between each call.
ggplot(b, aes(as.numeric(stage), Expression)) +
geom_point() +
geom_smooth(data=b[b$stage %in% c("A", "B"),], linetype = "dashed", span = 0.8) +
geom_smooth(data=b[b$stage %in% c("B", "C", "D"),], linetype = "solid", span = 0.8) +
geom_smooth(data=b[b$stage %in% c("D", "E"),], linetype = "dashed",span = 0.8) +
scale_linetype_manual(values=c(2,1,2)) +
guides(linetype=FALSE) +
scale_x_continuous(breaks = as.numeric(b$stage), labels = b$stage, minor_breaks = NULL)
Link to sub-optimal solution
Thanks
For completeness, I will post here the solution offered by user OTStats in the comments above:
ggplot(b, aes(as.numeric(stage), Expression)) +
geom_point() +
geom_smooth(data=b[b$stage %in% c("A", "B"),], linetype = "dashed", span = 0.8,se = FALSE) +
geom_smooth(data=b[b$stage %in% c("B", "C", "D"),], linetype = "solid", span = 0.8, se = FALSE) +
geom_smooth(data=b[b$stage %in% c("D", "E"),], linetype = "dashed",span = 0.8, se = FALSE) +
geom_smooth(linetype = "blank",span = 0.4) +
guides(linetype=FALSE) +
scale_x_continuous(breaks = as.numeric(b$stage), labels = b$stage, minor_breaks = NULL)
Note that the level of smoothing needs to be adjusted in the fourth call of geom_smooth to produce satisfactory results but, overall, this trick solves the question.
Link to solution

Faceted ggplot boxplot with different X axes by column [duplicate]

I am trying to make a faceted plot in ggplot2 where the y axis shows labels and the x axis should show line graphs with the value for each label in two different measures (which are on different scales). So far I have this:
Data <- structure(list(label = structure(
c(1L, 1L, 2L, 2L, 3L, 3L, 4L,
4L, 5L, 5L, 6L, 6L), .Label = c("A", "B", "C", "D", "E", "F"), class = "factor"),
facet = structure(c(1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L,
1L, 2L), .Label = c("A", "B"), class = "factor"), value = c(0.0108889081049711,
0.37984336540103, 0.0232500876998529, 0.777756493305787,
0.0552913920022547, 0.920194681268185, 0.0370863009011373,
0.114463779143989, 0.00536034172400832, 0.469208759721369,
0.0412159096915275, 0.587875489378348), group = c(1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1)), .Names = c("label", "facet",
"value", "group"), row.names = c(NA, -12L), class = "data.frame")
ggplot(Data, aes(x = label, y = value, group = group)) + geom_line() +
facet_grid(~ facet, scales = "free") + coord_flip()
Which creates the following plot:
The problem is that the measures are on different scales and I would prefer the A plot to have x limits from 0 to 0.1 and the B plot to have x limits from 0 to 1. I thought scales = "free" should fix this but it doesn't change the plot.
I came up with something similar to df239:
ggplot(Data, aes(y = label, x = value, group=group)) + geom_path() +
facet_wrap( ~ facet, scales = "free")
Note you have to use geom_path, and take care with the ordering of your points because just switching x and y is not the same as coord_flip (which as noted in the other answer isn't supported with facet_wrap).
Change axes orientation manually, the problem is: *ggplot2 does not currently support free scales with a non-cartesian coord or coord_flip.*
ggplot(Data, aes(y = label, x = value, group = group)) + geom_line() +
facet_grid(~ facet, scales = "free")

qplot limit of facets [duplicate]

I am trying to make a faceted plot in ggplot2 where the y axis shows labels and the x axis should show line graphs with the value for each label in two different measures (which are on different scales). So far I have this:
Data <- structure(list(label = structure(
c(1L, 1L, 2L, 2L, 3L, 3L, 4L,
4L, 5L, 5L, 6L, 6L), .Label = c("A", "B", "C", "D", "E", "F"), class = "factor"),
facet = structure(c(1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L,
1L, 2L), .Label = c("A", "B"), class = "factor"), value = c(0.0108889081049711,
0.37984336540103, 0.0232500876998529, 0.777756493305787,
0.0552913920022547, 0.920194681268185, 0.0370863009011373,
0.114463779143989, 0.00536034172400832, 0.469208759721369,
0.0412159096915275, 0.587875489378348), group = c(1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1)), .Names = c("label", "facet",
"value", "group"), row.names = c(NA, -12L), class = "data.frame")
ggplot(Data, aes(x = label, y = value, group = group)) + geom_line() +
facet_grid(~ facet, scales = "free") + coord_flip()
Which creates the following plot:
The problem is that the measures are on different scales and I would prefer the A plot to have x limits from 0 to 0.1 and the B plot to have x limits from 0 to 1. I thought scales = "free" should fix this but it doesn't change the plot.
I came up with something similar to df239:
ggplot(Data, aes(y = label, x = value, group=group)) + geom_path() +
facet_wrap( ~ facet, scales = "free")
Note you have to use geom_path, and take care with the ordering of your points because just switching x and y is not the same as coord_flip (which as noted in the other answer isn't supported with facet_wrap).
Change axes orientation manually, the problem is: *ggplot2 does not currently support free scales with a non-cartesian coord or coord_flip.*
ggplot(Data, aes(y = label, x = value, group = group)) + geom_line() +
facet_grid(~ facet, scales = "free")

Different axis limits per facet in ggplot2

I am trying to make a faceted plot in ggplot2 where the y axis shows labels and the x axis should show line graphs with the value for each label in two different measures (which are on different scales). So far I have this:
Data <- structure(list(label = structure(
c(1L, 1L, 2L, 2L, 3L, 3L, 4L,
4L, 5L, 5L, 6L, 6L), .Label = c("A", "B", "C", "D", "E", "F"), class = "factor"),
facet = structure(c(1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L, 1L, 2L,
1L, 2L), .Label = c("A", "B"), class = "factor"), value = c(0.0108889081049711,
0.37984336540103, 0.0232500876998529, 0.777756493305787,
0.0552913920022547, 0.920194681268185, 0.0370863009011373,
0.114463779143989, 0.00536034172400832, 0.469208759721369,
0.0412159096915275, 0.587875489378348), group = c(1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1)), .Names = c("label", "facet",
"value", "group"), row.names = c(NA, -12L), class = "data.frame")
ggplot(Data, aes(x = label, y = value, group = group)) + geom_line() +
facet_grid(~ facet, scales = "free") + coord_flip()
Which creates the following plot:
The problem is that the measures are on different scales and I would prefer the A plot to have x limits from 0 to 0.1 and the B plot to have x limits from 0 to 1. I thought scales = "free" should fix this but it doesn't change the plot.
I came up with something similar to df239:
ggplot(Data, aes(y = label, x = value, group=group)) + geom_path() +
facet_wrap( ~ facet, scales = "free")
Note you have to use geom_path, and take care with the ordering of your points because just switching x and y is not the same as coord_flip (which as noted in the other answer isn't supported with facet_wrap).
Change axes orientation manually, the problem is: *ggplot2 does not currently support free scales with a non-cartesian coord or coord_flip.*
ggplot(Data, aes(y = label, x = value, group = group)) + geom_line() +
facet_grid(~ facet, scales = "free")

Resources