[英]Plot background colour in gradient
此代碼生成下面的第一個圖:
water.height <- seq(0, 5, 1)
y <- seq(0, 1500, length.out = 6)
df <- data.frame(water.height, y)
library(ggplot2)
ggplot(df, aes(water.height, y)) + geom_blank()+ theme_bw()
我在這個藍色背景下拍照:
我可以使用R代碼生成相同的藍色背景嗎?
注釋中給出了ggplot2方法的相關鏈接。 從那里復制:
library(grid)
g <- rasterGrob(blues9, width=unit(1,"npc"), height = unit(1,"npc"),
interpolate = TRUE)
# grid.draw(g)
library(ggplot2)
ggplot(mtcars, aes(factor(cyl))) + # add gradient background
annotation_custom(g, xmin=-Inf, xmax=Inf, ymin=-Inf, ymax=Inf) +
geom_bar() # add data layer
我自己的方法:
像往常一樣,我無法與baptiste解決網格圖形問題的簡單優雅競爭,但這是我的方法,因為我去了所有的工作:
gg.background.fill <- function(gg.plot, cols = "white", which = "x") {
#does not work with facets
stopifnot(which %in% c("x", "y"))
which1 <- if (which == "x") "width" else "height"
require(gridExtra)
g <- ggplotGrob(gg.plot)
#g <- ggplotGrob(p)
gg <- g$grobs
findIt <- vapply(gg, function(x) grepl("GRID.gTree", x$name, fixed = TRUE), TRUE)
n1 <- getGrob(gg[findIt][[1]], "grill.gTree", grep=TRUE)$name
n2 <- getGrob(gg[findIt][[1]], "panel.background.rect", grep=TRUE)$name
gg[findIt][[1]]$children[[n1]]$children[[n2]]$gp$fill <- cols
x <- gg[findIt][[1]]$children[[n1]]$children[[n2]][[which]]
w <- gg[findIt][[1]]$children[[n1]]$children[[n2]][[which1]]
attr <- attributes(x)
x <- seq(0 + c(w)/length(cols)/2, 1 - c(w)/length(cols)/2, length.out = length(cols))
attributes(x) <- attr
gg[findIt][[1]]$children[[n1]]$children[[n2]][[which]] <- x
w <- c(w)/length(cols)
attributes(w) <- attr
gg[findIt][[1]]$children[[n1]]$children[[n2]][[which1]] <- w
g$grobs <- gg
class(g) = c("arrange", "ggplot", class(g))
g
}
p1 <- gg.background.fill(p, colorRampPalette(c("red", "blue"))(100))
print(p1)
p2 <- gg.background.fill(p, colorRampPalette(c("red", "blue"))(100), "y")
print(p2)
這會修改可能被視為優勢的現有背景,但與annotation_custom
方法相比,它不適用於分面。 這需要做更多的工作。
我們想使用線性漸變作為繪圖的背景。
讓我們從一個數字在0和1之間的矩陣開始。
# The angle of our linear gradient
deg <- 45
rad <- deg / (180 / pi)
# A 5x5 matrix
n <- 5
mat <- matrix(data = 0, ncol = n, nrow = n)
# Let's fill in the matrix.
for (i in 1:n) {
for (j in 1:n) {
mat[i, j] <- (i / n) * cos(rad) + (j / n) * sin(rad)
}
}
我們得到了什么?
mat
#> [,1] [,2] [,3] [,4] [,5]
#> [1,] 0.2828427 0.4242641 0.5656854 0.7071068 0.8485281
#> [2,] 0.4242641 0.5656854 0.7071068 0.8485281 0.9899495
#> [3,] 0.5656854 0.7071068 0.8485281 0.9899495 1.1313708
#> [4,] 0.7071068 0.8485281 0.9899495 1.1313708 1.2727922
#> [5,] 0.8485281 0.9899495 1.1313708 1.2727922 1.4142136
這看起來非常接近我們想要的。
現在,讓我們將值鉗制在0和1之間。
mat <- mat - min(mat)
mat <- mat / max(mat)
mat
#> [,1] [,2] [,3] [,4] [,5]
#> [1,] 0.000 0.125 0.250 0.375 0.500
#> [2,] 0.125 0.250 0.375 0.500 0.625
#> [3,] 0.250 0.375 0.500 0.625 0.750
#> [4,] 0.375 0.500 0.625 0.750 0.875
#> [5,] 0.500 0.625 0.750 0.875 1.000
好多了!
讓我們使用grid::rasterGrob()
來制作一個圖形對象並繪制它。
library(grid)
g <- rasterGrob(
image = mat,
width = unit(1, "npc"),
height = unit(1, "npc"),
interpolate = TRUE
)
grid.newpage()
grid.draw(g)
由於我們有一個grob,我們可以使用ggplot2::annotation_custom()
將它添加到ggplot2圖中。
library(ggplot2)
ggplot(mtcars, aes(factor(cyl))) +
annotation_custom(
grob = g, xmin = -Inf, xmax = Inf, ymin = -Inf, ymax = Inf
) +
geom_bar()
萬歲! 我們做到了。 但我們還沒有完成。
幾點說明:
請隨意復制下面的make_gradient()
函數並對其進行改進。
library(ggplot2)
library(grid)
library(RColorBrewer)
make_gradient <- function(deg = 45, n = 100, cols = blues9) {
cols <- colorRampPalette(cols)(n + 1)
rad <- deg / (180 / pi)
mat <- matrix(
data = rep(seq(0, 1, length.out = n) * cos(rad), n),
byrow = TRUE,
ncol = n
) +
matrix(
data = rep(seq(0, 1, length.out = n) * sin(rad), n),
byrow = FALSE,
ncol = n
)
mat <- mat - min(mat)
mat <- mat / max(mat)
mat <- 1 + mat * n
mat <- matrix(data = cols[round(mat)], ncol = n)
grid::rasterGrob(
image = mat,
width = unit(1, "npc"),
height = unit(1, "npc"),
interpolate = TRUE
)
}
例1
g <- make_gradient(
deg = 45, n = 500, cols = brewer.pal(9, "Spectral")
)
ggplot(mtcars, aes(factor(cyl))) +
annotation_custom(
grob = g, xmin = -Inf, xmax = Inf, ymin = -Inf, ymax = Inf
) +
geom_bar()
例2
g <- make_gradient(
deg = 180, n = 500, cols = brewer.pal(9, "RdBu")
)
ggplot(mtcars, aes(factor(cyl))) +
annotation_custom(
grob = g, xmin = -Inf, xmax = Inf, ymin = -Inf, ymax = Inf
) +
geom_bar()
由reprex包創建於2019-02-06(v0.2.1)
我使用Kamil Slowikowski的例子來構建一個更簡單的函數,它根據一系列值生成線性漸變。 如果你在三個變量之間存在某種關系(例如, y~x*z
,其中z
也隨x
變化),這可能是有用的。 然后你只需繪制y~x
並在背景中將z~x
作為顏色漸變。
water.height <- seq(0, 5, 1)
y <- seq(0, 1500, length.out = 6)
z <- rnorm(6, 10, 1)
df <- data.frame(water.height, y, z)
grad_by_val <- function(x, y, cols = blues9) {
require(grid)
y <- y[order(x)]
ys <- (y - min(y)) / diff(range(y))
cols <- colorRamp(cols)(ys) / 256
colnames(cols) <- c("red", "green", "blue")
cols <- apply(cols, 1, function(z) do.call(rgb, as.list(z)))
mat <- matrix(cols, ncol = length(x))
rasterGrob(
image = mat,
width = unit(1, "npc"),
height = unit(1, "npc"),
interpolate = TRUE
)
}
library(ggplot2)
ggplot(df, aes(water.height, y)) + geom_blank() + theme_bw() +
annotation_custom(
grob = grad_by_val(df$water.height, df$z),
xmin = -Inf,
xmax = Inf,
ymin = -Inf,
ymax = Inf
) +
geom_point(
size = 5,
color = "#FFFFFF",
fill = "#000000",
shape = 21
)
要添加圖例,請參閱此處 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.