用 scale_fill_manual 重新创建 scale_fill_brewer
recreate scale_fill_brewer with scale_fill_manual
我想了解包 ggplot2
的 scale_fill_brewer
和 scale_fill_manual
之间的联系。
首先,生成一个填充颜色的 ggplot:
library(ggplot2)
p <- ggplot(data = mtcars, aes(x = mpg, y = wt,
group = cyl, fill = factor(cyl))) +
geom_area(position = 'stack')
# apply ready-made palette with scale_fill_brewer from ggplot2
p + scale_fill_brewer(palette = "Blues")
现在,用scale_fill_manual
复制
library(RColorBrewer)
p + scale_fill_manual(values = brewer.pal(3, "Blues"))
其中 3 是数据中 fill-colors 的数量。为了方便起见,我使用了 RColorBrewer
.
包的 brewer.pal
函数
据我了解,scale_fill_brewer
的便利之处在于它会自动计算数据中唯一级别的数量(本例中为 3)。这是我的复制尝试:
p + scale_fill_manual(values = brewer.pal(length(levels(factor(mtcars$cyl))), "Blues"))
我的问题是:scale_fill_brewer
如何计算数据中的水平数?
我有兴趣了解 fill_color_brewer
的幕后工作。如果我将更用户友好的 fill_color_brewer
替换为像上面那样更扭曲的 scale_fill_manual
实现,我 运行 可能会遇到任何困难。
阅读源代码:
scale_fill_brewer
function (..., type = "seq", palette = 1) {
discrete_scale("fill", "brewer", brewer_pal(type, palette), ...)
}
我无法看穿 scale_fill_brewer
如何计算数据中唯一级别的数量。也许隐藏在 ...
?
编辑:函数 scale_fill_brewer
在哪里接收指令来计算数据中的级别数?它是在 "seq"
还是在 ...
或其他地方?
discrete_scale
函数错综复杂,我迷路了。这是它的参数:
discrete_scale <- function(aesthetics, scale_name, palette, name = NULL,
breaks = waiver(), labels = waiver(), legend = NULL, limits = NULL,
expand = waiver(), na.value = NA, drop = TRUE, guide="legend") {
这是否计算了级别数?
追踪它的最简单方法是从 (1) 设置情节数据结构和 (2) 解决 美学的角度思考。它使用 S3,所以分支是隐式的
设置调用序列
[比例-brewer.R]scale_fill_brewer(type="seq", palette="Blues")
[scale-.R] discrete_scale(...)
- return 表示比例的对象
structure(list(
call = match.call(),
aesthetics = aesthetics,
scale_name = scale_name,
palette = palette,
range = DiscreteRange$new(), ## this is scales::DiscreteRange
...), , class = c(scale_name, "discrete", "scale"))
解析调用顺序
- [plot-build.R]
ggplot_build(plot)
- 对于非位置尺度,应用 scales_train_df
# Train and map non-position scales
npscales <- scales$non_position_scales() ## scales is plot$scales, S4 type Scales
if (npscales$n() > 0) {
lapply(data, scales_train_df, scales = npscales)
data <- lapply(data, scales_map_df, scales = npscales)
}
[scales-.r] scales_train_df(...)
- 再次遍历 scales$scales (list)
[scale-.r] scale_train_df(...)
- 再次迭代
[scale-.r] scale_train(...)
- S3 通用函数
[scale-.r] scale_train.discrete(...)
- 差不多了...
scale$range$train(x, drop = scale$drop)
- 但是 scale$range 是一个 DiscreteRange 实例,所以它调用
(scales::DiscreteRange$new())$train
,它会覆盖 scale$range!
range <<- train_discrete(x, range, drop)
scales:::train_discrete(...)
- 又一次,差不多了...
scales:::discrete_range(...)
- 仍然没有..
scales:::clevels(...)
- 就是这样!
至此,scale$range
已被因子水平覆盖。将调用堆栈展开到 #1,我们现在调用 scales_map_df
- [plot-build.R]
ggplot_build(plot)
- 对于非位置尺度,应用 scales_train_df
# Train and map non-position scales
npscales <- scales$non_position_scales() ## scales is plot$scales, S4 type Scales
if (npscales$n() > 0) {
lapply(data, scales_train_df, scales = npscales)
data <- lapply(data, scales_map_df, scales = npscales)
}
[scales-.r] scale_maps_df(...)
- 迭代
[scale-.r] scale_map_df(...)
- 迭代
[scale-.r] scale_map.discrete
- 填满调色板(非位置比例!)
scale_map.discrete <- 函数(比例,x,限制 = scale_limits(比例)){
n <-总和(!is.na(限制))
pal <- scale$调色板(n)
...
}
我想了解包 ggplot2
的 scale_fill_brewer
和 scale_fill_manual
之间的联系。
首先,生成一个填充颜色的 ggplot:
library(ggplot2)
p <- ggplot(data = mtcars, aes(x = mpg, y = wt,
group = cyl, fill = factor(cyl))) +
geom_area(position = 'stack')
# apply ready-made palette with scale_fill_brewer from ggplot2
p + scale_fill_brewer(palette = "Blues")
现在,用scale_fill_manual
library(RColorBrewer)
p + scale_fill_manual(values = brewer.pal(3, "Blues"))
其中 3 是数据中 fill-colors 的数量。为了方便起见,我使用了 RColorBrewer
.
brewer.pal
函数
据我了解,scale_fill_brewer
的便利之处在于它会自动计算数据中唯一级别的数量(本例中为 3)。这是我的复制尝试:
p + scale_fill_manual(values = brewer.pal(length(levels(factor(mtcars$cyl))), "Blues"))
我的问题是:scale_fill_brewer
如何计算数据中的水平数?
我有兴趣了解 fill_color_brewer
的幕后工作。如果我将更用户友好的 fill_color_brewer
替换为像上面那样更扭曲的 scale_fill_manual
实现,我 运行 可能会遇到任何困难。
阅读源代码:
scale_fill_brewer
function (..., type = "seq", palette = 1) {
discrete_scale("fill", "brewer", brewer_pal(type, palette), ...)
}
我无法看穿 scale_fill_brewer
如何计算数据中唯一级别的数量。也许隐藏在 ...
?
编辑:函数 scale_fill_brewer
在哪里接收指令来计算数据中的级别数?它是在 "seq"
还是在 ...
或其他地方?
discrete_scale
函数错综复杂,我迷路了。这是它的参数:
discrete_scale <- function(aesthetics, scale_name, palette, name = NULL,
breaks = waiver(), labels = waiver(), legend = NULL, limits = NULL,
expand = waiver(), na.value = NA, drop = TRUE, guide="legend") {
这是否计算了级别数?
追踪它的最简单方法是从 (1) 设置情节数据结构和 (2) 解决 美学的角度思考。它使用 S3,所以分支是隐式的
设置调用序列
[比例-brewer.R]
scale_fill_brewer(type="seq", palette="Blues")
[scale-.R]
discrete_scale(...)
- return 表示比例的对象
structure(list(
call = match.call(),
aesthetics = aesthetics,
scale_name = scale_name,
palette = palette,
range = DiscreteRange$new(), ## this is scales::DiscreteRange
...), , class = c(scale_name, "discrete", "scale"))
解析调用顺序
- [plot-build.R]
ggplot_build(plot)
- 对于非位置尺度,应用 scales_train_df
# Train and map non-position scales
npscales <- scales$non_position_scales() ## scales is plot$scales, S4 type Scales
if (npscales$n() > 0) {
lapply(data, scales_train_df, scales = npscales)
data <- lapply(data, scales_map_df, scales = npscales)
}
[scales-.r]
scales_train_df(...)
- 再次遍历 scales$scales (list)[scale-.r]
scale_train_df(...)
- 再次迭代[scale-.r]
scale_train(...)
- S3 通用函数[scale-.r]
scale_train.discrete(...)
- 差不多了...
scale$range$train(x, drop = scale$drop)
- 但是 scale$range 是一个 DiscreteRange 实例,所以它调用
(scales::DiscreteRange$new())$train
,它会覆盖 scale$range!
range <<- train_discrete(x, range, drop)
scales:::train_discrete(...)
- 又一次,差不多了...scales:::discrete_range(...)
- 仍然没有..scales:::clevels(...)
- 就是这样!
至此,scale$range
已被因子水平覆盖。将调用堆栈展开到 #1,我们现在调用 scales_map_df
- [plot-build.R]
ggplot_build(plot)
- 对于非位置尺度,应用 scales_train_df
# Train and map non-position scales
npscales <- scales$non_position_scales() ## scales is plot$scales, S4 type Scales
if (npscales$n() > 0) {
lapply(data, scales_train_df, scales = npscales)
data <- lapply(data, scales_map_df, scales = npscales)
}
[scales-.r]
scale_maps_df(...)
- 迭代[scale-.r]
scale_map_df(...)
- 迭代[scale-.r]
scale_map.discrete
- 填满调色板(非位置比例!)scale_map.discrete <- 函数(比例,x,限制 = scale_limits(比例)){ n <-总和(!is.na(限制)) pal <- scale$调色板(n) ... }