我正在尝试了解包scale_fill_brewer
的{{1}}和scale_fill_manual
之间的关联。
首先,生成一个填充颜色的ggplot:
ggplot2
现在,使用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
其中3是数据中的填充颜色数。为方便起见,我使用了包library(RColorBrewer)
p + scale_fill_manual(values = brewer.pal(3, "Blues"))
的{{1}}函数。
据我了解,brewer.pal
的便利性在于它会自动计算数据中唯一级别的数量(本例中为3)。这是我复制的尝试:
RColorBrewer
我的问题是:scale_fill_brewer
如何计算数据中的关卡数量?
我有兴趣了解其他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"
功能错综复杂,我迷路了。以下是其论点:
...
是否有任何计算级别数?
答案 0 :(得分:3)
最简单的方法是跟踪它是考虑(1)设置绘图数据结构,以及(2)解析美学。它使用S3,因此分支是隐含的
设置调用序列
[scale-brewer.R] scale_fill_brewer(type="seq", palette="Blues")
[scale-.R] discrete_scale(...)
- 返回表示比例的对象
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"))
解析调用序列
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(...)
- 再次通过尺度$ scale(列表)进行迭代
[scale-.r] scale_train_df(...)
- 再次迭代
[scale-.r] scale_train(...)
- S3泛函
[scale-.r] scale_train.discrete(...)
- 差不多......
scale$range$train(x, drop = scale$drop)
(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
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(...)
- iterate
[scale-.r] scale_map.discrete
- 填充调色板(非位置刻度!)
scale_map.discrete&lt; - function(scale,x,limits = scale_limits(scale)){ n&lt; - sum(!is.na(limits)) pal&lt; - scale $ palette(n) ... }