R 空心柱状图或几何步分格
我想画一个空心的柱状图,里面没有竖线,只有一个轮廓。我找不到任何方法来使用R 空心柱状图或几何步分格,r,ggplot2,ggproto,R,Ggplot2,Ggproto,我想画一个空心的柱状图,里面没有竖线,只有一个轮廓。我找不到任何方法来使用geom\u直方图。geom\u步骤+stat\u bin组合似乎可以完成这项工作。但是,geom_step+stat_bin的料仓根据步骤的方向=参数值向右或向左移动半个料仓。它似乎在做它的“步骤”WRT bin中心。有没有办法改变这种行为,让它在箱子边缘执行“步骤” 下面是一个例子: d <- data.frame(x=rnorm(1000)) qplot(x, data=d, geom="histogram",
geom\u直方图
。geom\u步骤
+stat\u bin
组合似乎可以完成这项工作。但是,geom_step
+stat_bin
的料仓根据步骤的方向=
参数值向右或向左移动半个料仓。它似乎在做它的“步骤”WRT bin中心。有没有办法改变这种行为,让它在箱子边缘执行“步骤”
下面是一个例子:
d <- data.frame(x=rnorm(1000))
qplot(x, data=d, geom="histogram",
breaks=seq(-4,4,by=.5), color=I("red"), fill = I("transparent")) +
geom_step(stat="bin", breaks=seq(-4,4,by=.5), color="black", direction="vh")
d这并不理想,但这是我能想到的最好办法:
h <- hist(d$x,breaks=seq(-4,4,by=.5))
d1 <- data.frame(x = h$breaks,y = c(h$counts,NA))
ggplot() +
geom_histogram(data = d,aes(x = x),breaks = seq(-4,4,by=.5),
color = "red",fill = "transparent") +
geom_step(data = d1,aes(x = x,y = y),stat = "identity")
h另一种选择,也不太理想:
qplot(x, data=d, geom="histogram", breaks=seq(-4,4,by=.5), color=I("red"), fill = I("transparent")) +
stat_summary(aes(x=round(x * 2 - .5) / 2, y=1), fun.y=length, geom="step")
缺少一些垃圾箱,如果你有点乱的话,你可以把它们放回去。唯一(有点毫无意义)的好处是,它在ggplot
中比@Joran的答案更重要,尽管这也是有争议的
又是一个。使用ggplot\u build
构建直方图的plot对象以进行渲染。从该对象中提取x
和y
值,用于geom\u步骤
。使用by
偏移x
值
by <- 0.5
p1 <- ggplot(data = d, aes(x = x)) +
geom_histogram(breaks = seq(from = -4, to = 4, by = by),
color = "red", fill = "transparent")
df <- ggplot_build(p1)$data[[1]][ , c("x", "y")]
p1 +
geom_step(data = df, aes(x = x - by/2, y = y))
我建议制作一个新的几何图形,如下所示:
library(ggplot2)
library(proto)
geom_stephist <- function(mapping = NULL, data = NULL, stat="bin", position="identity", ...) {
GeomStepHist$new(mapping=mapping, data=data, stat=stat, position=position, ...)
}
GeomStepHist <- proto(ggplot2:::Geom, {
objname <- "stephist"
default_stat <- function(.) StatBin
default_aes <- function(.) aes(colour="black", size=0.5, linetype=1, alpha = NA)
reparameterise <- function(., df, params) {
transform(df,
ymin = pmin(y, 0), ymax = pmax(y, 0),
xmin = x - width / 2, xmax = x + width / 2, width = NULL
)
}
draw <- function(., data, scales, coordinates, ...) {
data <- as.data.frame(data)[order(data$x), ]
n <- nrow(data)
i <- rep(1:n, each=2)
newdata <- rbind(
transform(data[1, ], x=xmin, y=0),
transform(data[i, ], x=c(rbind(data$xmin, data$xmax))),
transform(data[n, ], x=xmax, y=0)
)
rownames(newdata) <- NULL
GeomPath$draw(newdata, scales, coordinates, ...)
}
guide_geom <- function(.) "path"
})
库(ggplot2)
图书馆(原型)
geom_Stephest我今天早些时候回答了我自己的评论:这里是@RosenMatev的答案的修改版本,使用ggproto更新了v2(ggplot2_2.0.0):
GeomStepHist <- ggproto("GeomStepHist", GeomPath,
required_aes = c("x"),
draw_panel = function(data, panel_scales, coord, direction) {
data <- as.data.frame(data)[order(data$x), ]
n <- nrow(data)
i <- rep(1:n, each=2)
newdata <- rbind(
transform(data[1, ], x=x - width/2, y=0),
transform(data[i, ], x=c(rbind(data$x-data$width/2, data$x+data$width/2))),
transform(data[n, ], x=x + width/2, y=0)
)
rownames(newdata) <- NULL
GeomPath$draw_panel(newdata, panel_scales, coord)
}
)
geom_step_hist <- function(mapping = NULL, data = NULL, stat = "bin",
direction = "hv", position = "stack", na.rm = FALSE,
show.legend = NA, inherit.aes = TRUE, ...) {
layer(
data = data,
mapping = mapping,
stat = stat,
geom = GeomStepHist,
position = position,
show.legend = show.legend,
inherit.aes = inherit.aes,
params = list(
direction = direction,
na.rm = na.rm,
...
)
)
}
GeomStephest一个简单的方法来做一些类似于@Rosen Matev的事情(这不适用于@julou提到的ggplot2_2.0.0),我只想
1) 手动计算箱子的值(使用如下所示的小功能)
2) 使用geom_步骤()
希望这有帮助
geom_step_hist<- function(d,binw){
dd=NULL
bin=min(d$y) # this enables having a first value that is = 0 (to have the left vertical bar of the plot when using geom_step)
max=max(d$y)+binw*2 # this enables having a last value that is = 0 (to have the right vertical bar of the plot when using geom_step)
xx=NULL
yy=NULL
while(bin<=max){
n=length(temp$y[which(temp$y<bin & temp$y>=(bin-binw))])
yy=c(yy,n)
xx=c(xx,bin-binw)
bin=bin+binw
rm(n)
}
dd=data.frame(xx,yy)
return(dd)
}
hist=ggplot(dd,aes(x=xx,y=yy))+
geom_step()
geom\u step\u histTLDR:使用geom\u step(…,direction=“mid”)
自从Daniel Mastropietro和Dewey Dunnington将“mid”作为ggplot2 v3.0的geom_step
的方向
参数的附加选项以来,这变得容易多了:
库(ggplot2)
种子(1)
坦白地说,我喜欢这三种解决方案。这是一个很好的无缝破解!它甚至允许通常的简单镶嵌面和默认装箱。但最自然的解决方案可能是在geom_直方图中添加一个参数,以禁用内部垂直条。@VadimKhotilovich我认为参数选项很难,因为geom_直方图
是关于stat_bin
和geom_bar
的,而geom_bar
并没有真正设置为仅选择性地包括/排除其垂直边缘的一部分。@joran:这样的技术困难无法推翻“直方图不是条形图”(这是直接引自《图形语法》一书).一般来说,直方图表示分布,条形图用于比较类别。虽然ggplot2在bar+bin上实现了一个简单的别名直方图,但它不必保持这种状态。我要补充的是,直方图也不是阶梯图。@VadimKhotilovich没问题。事实上,我应该道歉,我在我被一些非常令人恼火的事情弄得晕头转向,这对我的影响太大了。我过去非常依赖geom_Stephest,但它不再适用于ggplot2 v2的ggproto(也称为ggplot2_2.0.0)。如果有人能以此为例说明如何在ggplot2_2.0.0中创建新的gem,那将非常有帮助。谢谢!感谢您将我指向ggplot_build。它提供了许多潜在有用的数据!不过,在这种特殊情况下,我会将其子集为[,c(“xmin”,“y”)]直接获取下边缘。不客气。是的,当“正常”的ggplot
选项用完时,沿着ggplot\u build
路径走会非常有成效。您还可以操作plot对象内的数据,然后使用grid
函数进行打印。现在有direction=“mid“
这正是它的作用(请参阅)
GeomStepHist <- ggproto("GeomStepHist", GeomPath,
required_aes = c("x"),
draw_panel = function(data, panel_scales, coord, direction) {
data <- as.data.frame(data)[order(data$x), ]
n <- nrow(data)
i <- rep(1:n, each=2)
newdata <- rbind(
transform(data[1, ], x=x - width/2, y=0),
transform(data[i, ], x=c(rbind(data$x-data$width/2, data$x+data$width/2))),
transform(data[n, ], x=x + width/2, y=0)
)
rownames(newdata) <- NULL
GeomPath$draw_panel(newdata, panel_scales, coord)
}
)
geom_step_hist <- function(mapping = NULL, data = NULL, stat = "bin",
direction = "hv", position = "stack", na.rm = FALSE,
show.legend = NA, inherit.aes = TRUE, ...) {
layer(
data = data,
mapping = mapping,
stat = stat,
geom = GeomStepHist,
position = position,
show.legend = show.legend,
inherit.aes = inherit.aes,
params = list(
direction = direction,
na.rm = na.rm,
...
)
)
}
geom_step_hist<- function(d,binw){
dd=NULL
bin=min(d$y) # this enables having a first value that is = 0 (to have the left vertical bar of the plot when using geom_step)
max=max(d$y)+binw*2 # this enables having a last value that is = 0 (to have the right vertical bar of the plot when using geom_step)
xx=NULL
yy=NULL
while(bin<=max){
n=length(temp$y[which(temp$y<bin & temp$y>=(bin-binw))])
yy=c(yy,n)
xx=c(xx,bin-binw)
bin=bin+binw
rm(n)
}
dd=data.frame(xx,yy)
return(dd)
}
hist=ggplot(dd,aes(x=xx,y=yy))+
geom_step()