ggplot2:如何在对数刻度上绘制水平线

时间:2015-11-17 05:31:56

标签: r ggplot2

我有以下数据框:

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")

所以,我尝试以下方法:

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")

我得到了情节,但没有水平线为0.05,只是因为生成了NaNs /警告信息:

  

1:在coord $ trans $ x $ transform(x)中:NaNs产生了   2:在trans $ transform(value)中:生成NaNs

这些NaNs来自哪里,因为我的x-scale是1到60,因此无法对日志进行评估(因为它不在范围内)。

那么,我做错了什么?

1 个答案:

答案 0 :(得分:3)

您可以通过以下两种方式之一获得水平线:(1)切换到scale_x_log10以获取对数比例并使用geom_abline(或geom_hline)。 (2)继续使用coord_trans并使用geom_segment创建水平线,设置x范围,使其不会进入负区域。

coord_transscale_x_log10表现不同。正如ggplot2 help page所说:

  

转换比例和转换比例之间的区别   坐标系是BEFORE之前发生的尺度转换   统计,然后协调转换。坐标   转型也改变了几何形状。

看似geom_ablinegeom_hlinecoord_trans尝试记录负值,返回NaN。使用geom_segment可以通过防止较低的x限制低于零来避免这种情况。 scale_x_log10不会发生此问题。此外,如果您查看下面的图表,您可以看到缩放版本中的某些直线在coord_trans版本中略微弯曲。如果要避免此失真,请使用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")

enter image description here