我试图回复想要对图进行一些更改的评论者...我正在使用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)
}
}
答案 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对象。
一个简单的例子:
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;
给你
然而,如果你添加上面的代码
p <- p + coord_cartesian(xlim=c(0,1))
p
&#13;
你得到了
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。 :(