为 geom_bar 图创建垂直颜色渐变
Creating a vertical color gradient for a geom_bar plot
我找了又找,但似乎找不到一种优雅的方法!
我有一个数据集 Data
,包含 Data$x
(日期)和 Data$y
(从 0 到 1 的数字)
我想在条形图中绘制它们:
ggplot(Data) + geom_bar(aes(x = x, y = y, fill = y, stat = "identity")) +
scale_fill_gradient2(low = "red", high = "green", mid = "yellow", midpoint = 0.90)
结果是这样的
但是,我想给每个条形一个垂直方向的渐变,范围从 0(红色)到 y(更绿,取决于 y)。有什么办法可以顺利完成吗?
我试过看看是否可以将图片作为 hack 强加到图表上,但我不能只将它强加到条形图上,除非以超级超级丑陋的方式。
据我所知不存在,但您可以操纵您的数据来生成它。
library(ggplot2)
df = data.frame(x=c(1:10),y=runif(10))
prepGradient <- function(x,y,spacing=max(y)/100){
stopifnot(length(x)==length(y))
df <- data.frame(x=x,y=y)
newDf = data.frame(x=NULL,y=NULL,z=NULL)
for (r in 1:nrow(df)){
n <- floor(df[r,"y"]/spacing)
for (s in c(1:n)){
tmp <- data.frame(x=df[r,"x"],y=spacing,z=s*spacing)
newDf <- rbind(newDf,tmp)
}
tmp <- data.frame(x=df[r,"x"],y=df[r,"y"]%%spacing,z=df[r,"y"])
newDf <- rbind(newDf,tmp)
}
return(newDf)
}
df2 <- prepGradient(df$x,df$y)
ggplot(df2,aes(x=x,y=y,fill=z)) +
geom_bar(stat="identity") +
scale_fill_gradient2(low="red", high="green", mid="yellow",midpoint=median(df$y))+
ggtitle('Vertical Gradient Example') +
theme_minimal()
另一个不太漂亮的 hack 使用 geom_segment
。 x 开始和结束位置(x
和 xend
)是硬编码的(- 0.4
;+ 0.4
),size
也是如此。这些数字需要根据 x 值的数量和 y 的范围进行调整。
# some toy data
d <- data.frame(x = 1:3, y = 1:3)
# interpolate values from zero to y and create corresponding number of x values
vals <- lapply(d$y, function(y) seq(0, y, by = 0.01))
y <- unlist(vals)
mid <- rep(d$x, lengths(vals))
d2 <- data.frame(x = mid - 0.4,
xend = mid + 0.4,
y = y,
yend = y)
ggplot(data = d2, aes(x = x, xend = xend, y = y, yend = yend, color = y)) +
geom_segment(size = 2) +
scale_color_gradient2(low = "red", mid = "yellow", high = "green",
midpoint = max(d2$y)/2)
一个可能会给您一些其他想法的相关问题:How to make gradient color filled timeseries plot in R
在回答
时发现了一种不那么笨拙的方法
library(tidyverse)
df <- data.frame(value = c(20, 50, 90),
group = c(1, 2, 3))
df_expanded <- df %>%
rowwise() %>%
summarise(group = group,
value = list(0:value)) %>%
unnest(cols = value)
df_expanded %>%
ggplot() +
geom_tile(aes(
x = group,
y = value,
fill = value,
width = 0.9
)) +
coord_flip() +
scale_fill_viridis_c(option = "C") +
theme(legend.position = "none")
我找了又找,但似乎找不到一种优雅的方法!
我有一个数据集 Data
,包含 Data$x
(日期)和 Data$y
(从 0 到 1 的数字)
我想在条形图中绘制它们:
ggplot(Data) + geom_bar(aes(x = x, y = y, fill = y, stat = "identity")) +
scale_fill_gradient2(low = "red", high = "green", mid = "yellow", midpoint = 0.90)
结果是这样的
但是,我想给每个条形一个垂直方向的渐变,范围从 0(红色)到 y(更绿,取决于 y)。有什么办法可以顺利完成吗?
我试过看看是否可以将图片作为 hack 强加到图表上,但我不能只将它强加到条形图上,除非以超级超级丑陋的方式。
据我所知不存在,但您可以操纵您的数据来生成它。
library(ggplot2)
df = data.frame(x=c(1:10),y=runif(10))
prepGradient <- function(x,y,spacing=max(y)/100){
stopifnot(length(x)==length(y))
df <- data.frame(x=x,y=y)
newDf = data.frame(x=NULL,y=NULL,z=NULL)
for (r in 1:nrow(df)){
n <- floor(df[r,"y"]/spacing)
for (s in c(1:n)){
tmp <- data.frame(x=df[r,"x"],y=spacing,z=s*spacing)
newDf <- rbind(newDf,tmp)
}
tmp <- data.frame(x=df[r,"x"],y=df[r,"y"]%%spacing,z=df[r,"y"])
newDf <- rbind(newDf,tmp)
}
return(newDf)
}
df2 <- prepGradient(df$x,df$y)
ggplot(df2,aes(x=x,y=y,fill=z)) +
geom_bar(stat="identity") +
scale_fill_gradient2(low="red", high="green", mid="yellow",midpoint=median(df$y))+
ggtitle('Vertical Gradient Example') +
theme_minimal()
另一个不太漂亮的 hack 使用 geom_segment
。 x 开始和结束位置(x
和 xend
)是硬编码的(- 0.4
;+ 0.4
),size
也是如此。这些数字需要根据 x 值的数量和 y 的范围进行调整。
# some toy data
d <- data.frame(x = 1:3, y = 1:3)
# interpolate values from zero to y and create corresponding number of x values
vals <- lapply(d$y, function(y) seq(0, y, by = 0.01))
y <- unlist(vals)
mid <- rep(d$x, lengths(vals))
d2 <- data.frame(x = mid - 0.4,
xend = mid + 0.4,
y = y,
yend = y)
ggplot(data = d2, aes(x = x, xend = xend, y = y, yend = yend, color = y)) +
geom_segment(size = 2) +
scale_color_gradient2(low = "red", mid = "yellow", high = "green",
midpoint = max(d2$y)/2)
一个可能会给您一些其他想法的相关问题:How to make gradient color filled timeseries plot in R
在回答
library(tidyverse)
df <- data.frame(value = c(20, 50, 90),
group = c(1, 2, 3))
df_expanded <- df %>%
rowwise() %>%
summarise(group = group,
value = list(0:value)) %>%
unnest(cols = value)
df_expanded %>%
ggplot() +
geom_tile(aes(
x = group,
y = value,
fill = value,
width = 0.9
)) +
coord_flip() +
scale_fill_viridis_c(option = "C") +
theme(legend.position = "none")