R:ggplot2:在轴

时间:2015-06-11 05:27:49

标签: r ggplot2

我试图回复想要对图进行一些更改的评论者...我正在使用ggplot2生成Kaplan-Meier曲线,并且评论者希望X轴从0开始。默认在ggkmTable中,在0和Y轴之间添加一些空格。我无法弄清楚要改变什么以使其看起来正确。 这是我的代码:

ggkmTable <- function(sfit, table=TRUE,returns = FALSE,
xlabs = "Time in Years", ylabs = "Survival Probability",
ystratalabs = NULL, ystrataname = NULL,
timeby = 100, main = "Kaplan-Meier Plot",
pval = TRUE, ...) {
    require(plyr)
    require(ggplot2)
    require(survival)
    require(gridExtra)
    if(is.null(ystratalabs)) {
        ystratalabs <- as.character(levels(summary(sfit)$strata))
    }
    m <- max(nchar(ystratalabs))
    if(is.null(ystrataname)) ystrataname <- "Strata"
    times <- seq(0, max(sfit$time), by = timeby)
    .df <- data.frame(time = sfit$time, n.risk = sfit$n.risk,
    n.event = sfit$n.event, surv = sfit$surv, strata = summary(sfit, censored = T)$strata,
    upper = sfit$upper, lower = sfit$lower)
    levels(.df$strata) <- ystratalabs
    zeros <- data.frame(time = 0, surv = 1, strata = factor(ystratalabs, levels=levels(.df$strata)),
    upper = 1, lower = 1)
    .df <- rbind.fill(zeros, .df)
    d <- length(levels(.df$strata))
    p <- ggplot(.df, aes(time, surv, group = strata)) +
    geom_step(aes(linetype = strata), size = 0.7) +
    theme_bw() +
    theme(axis.title.x = element_text(vjust = 0.5)) +
    scale_x_continuous(xlabs, breaks = times, limits = c(0, max(sfit$time))) +
    scale_y_continuous(ylabs, limits = c(0, 1)) +
    theme(panel.grid.minor = element_blank()) +
    theme(legend.position = "bottom") +
    theme(legend.key = element_rect(colour = NA)) +
    labs(linetype = ystrataname) +
    theme(plot.margin = unit(c(0, 1, .5, ifelse(m < 10, 1.5, 2.5)), "lines")) +
    ggtitle(main)
    if(pval) {
        sdiff <- survdiff(eval(sfit$call$formula), data = eval(sfit$call$data))
        pval <- pchisq(sdiff$chisq, length(sdiff$n)-1, lower.tail = FALSE)
        pvaltxt <- paste("p =", signif(pval, 3))
        p <- p + annotate("text", x = 0.6 * max(sfit$time), y = 0.1, label = pvaltxt)
    }

    ## Create a blank plot for place-holding
    ## .df <- data.frame()
    blank.pic <- ggplot(.df, aes(time, surv)) +
    geom_blank() +
    theme_bw() +
    theme(axis.text.x = element_blank(), axis.text.y = element_blank(),
    axis.title.x = element_blank(), axis.title.y = element_blank(),
    axis.ticks = element_blank(), panel.grid.major = element_blank(),
    panel.border = element_blank())
    if(table) {
        ## Create table graphic to include at-risk numbers
        risk.data <- data.frame(strata = summary(sfit, times = times, extend = TRUE)$strata,
        time = summary(sfit, times = times, extend = TRUE)$time,
        n.risk = summary(sfit, times = times, extend = TRUE)$n.risk)
        data.table <- ggplot(risk.data, aes(x = time, y = strata, label = format(n.risk, nsmall = 0))) +
        #, color = strata)) +
        geom_text(size = 3.5) +
        theme_bw() +
        scale_y_discrete(breaks = as.character(levels(risk.data$strata)), labels = ystratalabs) +
        # scale_y_discrete(#format1ter = abbreviate,
        # breaks = 1:3,
        # labels = ystratalabs) +
        scale_x_continuous("Numbers at risk", limits = c(0, max(sfit$time))) +
        theme(axis.title.x = element_text(size = 10, vjust = 1), panel.grid.major = element_blank(),
        panel.grid.minor = element_blank(), panel.border = element_blank(),
        axis.text.x = element_blank(), axis.ticks = element_blank(),
        axis.text.y = element_text(face = "bold", hjust = 1))
        data.table <- data.table + theme(legend.position = "none") +
        xlab(NULL) + ylab(NULL)
        data.table <- data.table +
        theme(plot.margin = unit(c(-1.5, 1, 0.1, ifelse(m < 10, 2.5, 3.5)-0.28 * m), "lines"))
        ## Plotting the graphs
        ## p <- ggplotGrob(p)
        ## p <- addGrob(p, textGrob(x = unit(.8, "npc"), y = unit(.25, "npc"), label = pvaltxt,
        ## gp = gpar(fontsize = 12)))
        grid.arrange(p, blank.pic, data.table,
        clip = FALSE, nrow = 3, ncol = 1,
        heights = unit(c(2, .1, .25),c("null", "null", "null")))
        if(returns) {
            a <- arrangeGrob(p, blank.pic, data.table, clip = FALSE,
            nrow = 3, ncol = 1, heights = unit(c(2, .1, .25),c("null", "null", "null")))
            return(a)
        }
    }
    else {
        ## p <- ggplotGrob(p)
        ## p <- addGrob(p, textGrob(x = unit(0.5, "npc"), y = unit(0.23, "npc"),
        ## label = pvaltxt, gp = gpar(fontsize = 12)))
        print(p)
        if(returns) return(p)
    }
}

2 个答案:

答案 0 :(得分:0)

使用:

scale_x_continuous("Numbers at risk", limits = c(0, max(sfit$time)), expand = c(0, 0))

如果需要,也可以在y轴上使用展开。

答案 1 :(得分:0)

首先是答案,然后是解释。

添加以下行:

coord_cartesian(xlim=c(0,max(sfit$time)))

到你的ggplot对象。

一个简单的例子:

&#13;
&#13;
df <- data.frame(c(runif(10,0,1)),runif(10,0,1))
names(df) <- c("x","y")

p <- ggplot(df, aes(x,y)) +
  geom_point() +
  scale_x_continuous(breaks=c(0,0.25,0.5,0.75,1.0),
                     labels=c("0","0.25","0.5","0.75","1.0"))
p
&#13;
&#13;
&#13;

给你

plot with undesired x-axis bounds

然而,如果你添加上面的代码

&#13;
&#13;
p <- p + coord_cartesian(xlim=c(0,1))
p
&#13;
&#13;
&#13;

你得到了

the exact x-axis bounds you wanted!

coord_cartesian()是你的朋友(以及你之后使用你的代码的任何人)IFF你绝对肯定任何[视觉上重要的]数据永远不会超出你在该功能中设置的范围。这是有据可查的;见Hadley's doc on this useful creature

要将它应用到上面的代码中并自己想象它......我需要知道&#34; sfit&#34;是(根据用户Pascal的深刻见解),可能是其他特殊事物。但要点是:

scale_x_continuous(及其姐妹scale_y_continuous等)不会严格限制您指定的EXACT参数。它们顾名思义,是的,&#34; scale&#34;轴根据函数(例如log10)。但是他们总是在极限范围内留下一个可爱的小缓冲区,假定美学上优先默认。

另一方面,

&#39; coord_cartesian`,DOES按照您的指定完全设置轴限制,删除所有超出这些边界的空间和数据,而不更改与整个数据字段相关的分析。但是不要接受我的话:阅读哈德利的恰当描述:

&#34;笛卡尔坐标系是最常见,最常见的坐标系。设置坐标系的限制将缩放绘图(就像你用放大镜看它一样),并且不会改变基础数据,如刻度上的设置限制。&#34;

要清楚,您可以在同一个ggplot对象中同时使用scale_x_continuous(和y)和coord_cartesian,因为它们可以执行不同的操作。前者为这些中断设置了中断和标签,后者是情节的框架(即视觉边界)。

另一个(脏的,脏的)解决方案是... photoshop。 :(