ggplot2: how to draw horizontal line on plot in lo

2019-08-18 06:10发布

问题:

I have the folllowing dataframe:

dput(AR.df)
structure(list(Type = structure(c(2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L), .Label = c("Complex-valued", "Magnitude-only"), class = "factor"), 
    AR.coef = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 15, 20, 25, 30, 
    35, 40, 45, 50, 55, 60, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 15, 
    20, 25, 30, 35, 40, 45, 50, 55, 60, 1, 2, 3, 4, 5, 6, 7, 
    8, 9, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 1, 2, 3, 
    4, 5, 6, 7, 8, 9, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 
    60, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 15, 20, 25, 30, 35, 40, 
    45, 50, 55, 60, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 15, 20, 25, 
    30, 35, 40, 45, 50, 55, 60), variable = structure(c(1L, 1L, 
    1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
    1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
    1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
    2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
    2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
    2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 
    3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 
    3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L), .Label = c("p=0", 
    "p=1", "p=phat"), class = "factor"), value = c(0.07226, 0.08482, 
    0.08634, 0.0863, 0.08832, 0.08863, 0.08771, 0.08636, 0.08752, 
    0.08778, 0.08732, 0.08855, 0.08868, 0.08801, 0.08806, 0.08765, 
    0.08774, 0.08592, 0.0868, 0.08616, 0.08737, 0.09057, 0.08722, 
    0.08768, 0.08819, 0.08816, 0.08758, 0.08601, 0.08687, 0.08712, 
    0.08619, 0.08774, 0.08792, 0.08701, 0.08729, 0.08641, 0.08674, 
    0.08532, 0.08635, 0.08557, 0.05503, 0.05573, 0.05482, 0.0537, 
    0.05441, 0.05439, 0.05503, 0.05373, 0.05463, 0.0536, 0.05401, 
    0.05508, 0.05347, 0.05356, 0.05408, 0.05376, 0.05383, 0.05316, 
    0.0529, 0.05322, 0.05275, 0.05406, 0.05331, 0.05251, 0.05265, 
    0.0533, 0.05365, 0.0517, 0.05242, 0.05254, 0.05238, 0.0535, 
    0.05166, 0.05166, 0.05294, 0.0523, 0.05215, 0.05196, 0.05144, 
    0.05184, 0.06526, 0.06671, 0.06451, 0.06327, 0.06431, 0.06467, 
    0.06463, 0.06328, 0.0639, 0.06346, 0.06308, 0.06458, 0.06291, 
    0.063, 0.06351, 0.06288, 0.06372, 0.06227, 0.06239, 0.06268, 
    0.05505, 0.05666, 0.05595, 0.055, 0.05503, 0.05568, 0.05579, 
    0.05407, 0.05474, 0.05509, 0.05486, 0.05593, 0.05412, 0.0544, 
    0.05526, 0.05475, 0.05454, 0.0543, 0.05399, 0.05438)), row.names = c(NA, 
-120L), .Names = c("Type", "AR.coef", "variable", "value"), class = "data.frame")

So, I try the following:

ggplot(AR.df, aes(x = AR.coef, y = value, linetype = variable, colour = Type)) +
    geom_line(size=1.25) + xlab("SNR") + ylab("False Positive Rate") +
        theme_bw() +
            theme(legend.justification=c(1,-0.2), legend.position=c(0.95,0.5), legend.text=element_text(size=11), legend.title=element_text(size=11), axis.title.x=element_text(size=14), axis.title.y=element_text(size = 14), legend.key = element_blank(), legend.background = element_rect(color="black",size = 0.1),legend.box = "horizontal") +
                scale_linetype_manual(values=c(6,4,1), labels = expression(p==0, p==1, p==hat(p)),name="AR order")  +
                    scale_colour_manual(values=cbPalette, name="Analysis Type") +
                        theme(legend.key.width=unit(3,"line")) + ylim(c(0.04,0.1))  +
                            guides(fill=guide_legend(ncol=2))  + coord_trans(x="log2") + scale_x_continuous(breaks=c(1:10,10*(2:6))) + geom_abline(aes(intercept=0.05, slope = 0), linetype="dotted")

and I get the plot, but no horizontal line at 0.05, simply because NaNs are produced/Warning messages:

1: In coord$trans$x$transform(x) : NaNs produced
2: In trans$transform(value) : NaNs produced

Where do these NaNs come from, since my x-scale is from 1 to 60, so zero is not possible for log to evaluate (because it is not in the range).

So, what am I doing wrong?

回答1:

You can get a horizontal line in one of two ways: (1) Switch to scale_x_log10 to get the log scale and use geom_abline (or geom_hline). (2) continue to use coord_trans and use geom_segment to create the horizontal line, setting the x-range so that it doesn't go into negative territory.

coord_trans and scale_x_log10 behave differently. As the ggplot2 help page says:

The difference between transforming the scales and transforming the coordinate system is that scale transformation occurs BEFORE statistics, and coordinate transformation afterwards. Coordinate transformation also changes the shape of geoms.

It looks like with geom_abline or geom_hline, coord_trans tries to take the log of a negative value, which returns NaN. Using geom_segment allows you to avoid this by preventing the lower x-limit from going below zero. This problem doesn't happen with scale_x_log10. Also, if you look at the plots below, you can see that some lines that are straight in the scaled version are slightly curved in the coord_trans version. If you want to avoid this distortion, use scale_x_log10.

ggplot(AR.df, aes(x = AR.coef, y = value, linetype = variable, colour = Type)) +
  geom_line(size=1.25) + 
  xlab("SNR") + ylab("False Positive Rate") +
  theme_bw() +
  scale_linetype_manual(values=c(6,4,1), 
                        labels = expression(p==0, p==1, p==hat(p)),name="AR order")  +
  guides(fill=guide_legend(ncol=2)) +
  scale_x_log10(breaks=c(1:10,10*(2:6))) +
  scale_y_continuous(breaks=seq(0.04,0.1,0.01), limits=c(0.04,0.1)) +
  geom_abline(slope=0, intercept=0.05) +
  #geom_hline(yintercept=0.05) + # You can do this instead of geom_abline
  ggtitle("scale_x_log10 + geom_abline")

ggplot(AR.df, aes(x = AR.coef, y = value, linetype = variable, colour = Type)) +
  geom_line(size=1.25) + 
  xlab("SNR") + ylab("False Positive Rate") +
  theme_bw() +
  scale_linetype_manual(values=c(6,4,1), 
                        labels = expression(p==0, p==1, p==hat(p)),name="AR order")  +
  ylim(c(0.04,0.1))  +
  guides(fill=guide_legend(ncol=2))  + 
  coord_trans(x="log2") + 
  scale_x_continuous(breaks=c(1:10,10*(2:6))) + 
  geom_segment(y=0.05,yend=0.05,x=0.01,xend=80, colour="black") +
  ggtitle("coord_trans + geom_segment")



标签: r ggplot2