如何将三角形添加到 R 中的 ggplot2 颜色条以指示超出范围的值?
How can I add triangles to a ggplot2 colorbar in R to indicate out of bound values?
我想使用 ggplot2
绘制绘图,其中一些填充值被剪裁,即高于或低于色标限制的值显示为 minimum/maximum 颜色。我可以这样工作,使用 limit
和 oob
(越界)的组合:
library(ggplot2)
library(scales)
ggplot() + ... + scale_fill_viridis(na.value="white", limit=c(0, 10), oob=squish)
但是颜色栏中没有信息表明存在超出限制的值。
如何在 ggplot 中重现这个 matplotlib 示例:
具体如何得到colorbar末端的三角形?
据我所知,在 ggplot2 中没有实现色条三角形末端的包(但如果有,请告诉我!)。但是,我们可以实现自己的。我们需要一个自定义指南的构造函数和一种绘制它的方法。大多数东西已经在 guide_colourbar()
和方法中实现了 class,所以我们需要做的只是标记我们自己的 class 并扩展 guide_gengrob
方法。下面的代码应该适用于垂直方向的颜色条。您需要了解有关 grid
软件包和 gtable
软件包的一些知识才能跟进。
library(ggplot2)
library(gtable)
library(grid)
my_triangle_colourbar <- function(...) {
guide <- guide_colourbar(...)
class(guide) <- c("my_triangle_colourbar", class(guide))
guide
}
guide_gengrob.my_triangle_colourbar <- function(...) {
# First draw normal colourbar
guide <- NextMethod()
# Extract bar / colours
is_bar <- grep("^bar$", guide$layout$name)
bar <- guide$grobs[[is_bar]]
extremes <- c(bar$raster[1], bar$raster[length(bar$raster)])
# Extract size
width <- guide$widths[guide$layout$l[is_bar]]
height <- guide$heights[guide$layout$t[is_bar]]
short <- min(convertUnit(width, "cm", valueOnly = TRUE),
convertUnit(height, "cm", valueOnly = TRUE))
# Make space for triangles
guide <- gtable_add_rows(guide, unit(short, "cm"),
guide$layout$t[is_bar] - 1)
guide <- gtable_add_rows(guide, unit(short, "cm"),
guide$layout$t[is_bar])
# Draw triangles
top <- polygonGrob(
x = unit(c(0, 0.5, 1), "npc"),
y = unit(c(0, 1, 0), "npc"),
gp = gpar(fill = extremes[1], col = NA)
)
bottom <- polygonGrob(
x = unit(c(0, 0.5, 1), "npc"),
y = unit(c(1, 0, 1), "npc"),
gp = gpar(fill = extremes[2], col = NA)
)
# Add triangles to guide
guide <- gtable_add_grob(
guide, top,
t = guide$layout$t[is_bar] - 1,
l = guide$layout$l[is_bar]
)
guide <- gtable_add_grob(
guide, bottom,
t = guide$layout$t[is_bar] + 1,
l = guide$layout$l[is_bar]
)
return(guide)
}
然后您可以使用自定义指南作为量表中的 guide
参数。
g <- ggplot(mtcars, aes(mpg, wt)) +
geom_point(aes(colour = drat))
g + scale_colour_viridis_c(
limits = c(3, 4), oob = scales::oob_squish,
guide = my_triangle_colourbar()
)
实际上并没有一种自然的方法来对越界值进行不同的着色,但是您可以将极值附近的非常小的切片设为不同的颜色。
g + scale_colour_gradientn(
colours = c("red", scales::viridis_pal()(255), "hotpink"),
limits = c(3, 4), oob = scales::oob_squish,
guide = my_triangle_colourbar()
)
由 reprex package (v1.0.0)
于 2021 年 7 月 19 日创建
三角形?不知道。颜色?您可以使用自定义值设置渐变,其中您的正常范围是手动定义的,而您的极端是其他东西。
library(ggplot2)
# example taken from ?viridis::scale_colour_viridis, even if I don't use that function
dsub <- subset(diamonds, x > 5 & x < 6 & y > 5 & y < 6)
dsub$diff <- with(dsub, sqrt(abs(x-y))* sign(x-y))
d <- ggplot(dsub, aes(x, y, colour=diff)) + geom_point()
d +
scale_color_gradientn(
colours=c("red", "red", "blue", "green", "yellow", "red", "red"),
values = c(0, 0.1-1e-9, 0.1, 0.5, 0.9, 0.9+1e-9, 1),
breaks = c(-0.51, -.4, 0, .4, .62),
label = function(z) replace(z, c(1, length(z)), c("Min", "Max"))) +
theme_bw()
我在每一端都加倍了 "red"
,这样相邻颜色就不会出现渐变过渡。你可以为一端选择不同的颜色(而在这种情况下,它是极高还是极低一目了然)。
我选择手动控制 values=
和 labels=
以包括任意点和极值标签。这可以根据您的喜好进行改进。
这样做的缺点是您必须手动定义绿色颜色;应该不会太难。我这里粗略的估算了一下,我相信你可以为内部渐变部分选择更好的颜色。
library(gg.layers)
library(ggplot2)
library(rcolors)
brk <- c(-Inf, -1, 0, 1, 3, 6, 9, Inf)
nbrk <- length(brk) - 1
cols <- get_color(rcolors$amwg256, nbrk)
g <- make_colorbar(
at = brk, col = cols, height = 1,
tck = 0.4,
space = "right",
legend.text.location = c(0.3, 0.5),
legend.text.just = c(0.5, 0.5),
# legend.text = list(fontfamily = "Times", cex = 1.1),
hjust = 0.05
)
p <- ggplot(mtcars, aes(mpg, disp)) + geom_point()
p + g
https://github.com/rpkgs/gg.layers
我想使用 ggplot2
绘制绘图,其中一些填充值被剪裁,即高于或低于色标限制的值显示为 minimum/maximum 颜色。我可以这样工作,使用 limit
和 oob
(越界)的组合:
library(ggplot2)
library(scales)
ggplot() + ... + scale_fill_viridis(na.value="white", limit=c(0, 10), oob=squish)
但是颜色栏中没有信息表明存在超出限制的值。
如何在 ggplot 中重现这个 matplotlib 示例:
具体如何得到colorbar末端的三角形?
据我所知,在 ggplot2 中没有实现色条三角形末端的包(但如果有,请告诉我!)。但是,我们可以实现自己的。我们需要一个自定义指南的构造函数和一种绘制它的方法。大多数东西已经在 guide_colourbar()
和方法中实现了 class,所以我们需要做的只是标记我们自己的 class 并扩展 guide_gengrob
方法。下面的代码应该适用于垂直方向的颜色条。您需要了解有关 grid
软件包和 gtable
软件包的一些知识才能跟进。
library(ggplot2)
library(gtable)
library(grid)
my_triangle_colourbar <- function(...) {
guide <- guide_colourbar(...)
class(guide) <- c("my_triangle_colourbar", class(guide))
guide
}
guide_gengrob.my_triangle_colourbar <- function(...) {
# First draw normal colourbar
guide <- NextMethod()
# Extract bar / colours
is_bar <- grep("^bar$", guide$layout$name)
bar <- guide$grobs[[is_bar]]
extremes <- c(bar$raster[1], bar$raster[length(bar$raster)])
# Extract size
width <- guide$widths[guide$layout$l[is_bar]]
height <- guide$heights[guide$layout$t[is_bar]]
short <- min(convertUnit(width, "cm", valueOnly = TRUE),
convertUnit(height, "cm", valueOnly = TRUE))
# Make space for triangles
guide <- gtable_add_rows(guide, unit(short, "cm"),
guide$layout$t[is_bar] - 1)
guide <- gtable_add_rows(guide, unit(short, "cm"),
guide$layout$t[is_bar])
# Draw triangles
top <- polygonGrob(
x = unit(c(0, 0.5, 1), "npc"),
y = unit(c(0, 1, 0), "npc"),
gp = gpar(fill = extremes[1], col = NA)
)
bottom <- polygonGrob(
x = unit(c(0, 0.5, 1), "npc"),
y = unit(c(1, 0, 1), "npc"),
gp = gpar(fill = extremes[2], col = NA)
)
# Add triangles to guide
guide <- gtable_add_grob(
guide, top,
t = guide$layout$t[is_bar] - 1,
l = guide$layout$l[is_bar]
)
guide <- gtable_add_grob(
guide, bottom,
t = guide$layout$t[is_bar] + 1,
l = guide$layout$l[is_bar]
)
return(guide)
}
然后您可以使用自定义指南作为量表中的 guide
参数。
g <- ggplot(mtcars, aes(mpg, wt)) +
geom_point(aes(colour = drat))
g + scale_colour_viridis_c(
limits = c(3, 4), oob = scales::oob_squish,
guide = my_triangle_colourbar()
)
实际上并没有一种自然的方法来对越界值进行不同的着色,但是您可以将极值附近的非常小的切片设为不同的颜色。
g + scale_colour_gradientn(
colours = c("red", scales::viridis_pal()(255), "hotpink"),
limits = c(3, 4), oob = scales::oob_squish,
guide = my_triangle_colourbar()
)
由 reprex package (v1.0.0)
于 2021 年 7 月 19 日创建三角形?不知道。颜色?您可以使用自定义值设置渐变,其中您的正常范围是手动定义的,而您的极端是其他东西。
library(ggplot2)
# example taken from ?viridis::scale_colour_viridis, even if I don't use that function
dsub <- subset(diamonds, x > 5 & x < 6 & y > 5 & y < 6)
dsub$diff <- with(dsub, sqrt(abs(x-y))* sign(x-y))
d <- ggplot(dsub, aes(x, y, colour=diff)) + geom_point()
d +
scale_color_gradientn(
colours=c("red", "red", "blue", "green", "yellow", "red", "red"),
values = c(0, 0.1-1e-9, 0.1, 0.5, 0.9, 0.9+1e-9, 1),
breaks = c(-0.51, -.4, 0, .4, .62),
label = function(z) replace(z, c(1, length(z)), c("Min", "Max"))) +
theme_bw()
我在每一端都加倍了 "red"
,这样相邻颜色就不会出现渐变过渡。你可以为一端选择不同的颜色(而在这种情况下,它是极高还是极低一目了然)。
我选择手动控制 values=
和 labels=
以包括任意点和极值标签。这可以根据您的喜好进行改进。
这样做的缺点是您必须手动定义绿色颜色;应该不会太难。我这里粗略的估算了一下,我相信你可以为内部渐变部分选择更好的颜色。
library(gg.layers)
library(ggplot2)
library(rcolors)
brk <- c(-Inf, -1, 0, 1, 3, 6, 9, Inf)
nbrk <- length(brk) - 1
cols <- get_color(rcolors$amwg256, nbrk)
g <- make_colorbar(
at = brk, col = cols, height = 1,
tck = 0.4,
space = "right",
legend.text.location = c(0.3, 0.5),
legend.text.just = c(0.5, 0.5),
# legend.text = list(fontfamily = "Times", cex = 1.1),
hjust = 0.05
)
p <- ggplot(mtcars, aes(mpg, disp)) + geom_point()
p + g
https://github.com/rpkgs/gg.layers