如何将单独的coord_cartesian()应用于“放大".进入facet_grid()的各个面板中? [英] How to apply separate coord_cartesian() to "zoom in" into individual panels of a facet_grid()?
问题描述
受到Q的启发找到弯曲的肘部/膝盖我开始玩smooth.spline()
.
Inspired by the Q Finding the elbow/knee in a curve I started to play around with smooth.spline()
.
尤其是,我想可视化参数df
(自由度)如何影响近似值以及一阶和二阶导数.请注意,此Q不是近似值,而是关于ggplot2
可视化中的特定问题(或边际情况).
In particular, I want to visualize how the parameter df
(degree of freedom) influences the approximation and the first and second derivative. Note that this Q is not about approximation but about a specific problem (or edge case) in visualisation with ggplot2
.
library(ggplot2)
ggplot(ap, aes(x, y)) +
geom_point(data = dp, alpha = 0.2) +
geom_line() +
facet_grid(deriv ~ df, scales = "free_y", labeller = label_both) +
theme_bw()
dp
是一个data.table,包含要寻找其近似值的数据点,而ap
是一个具有近似数据和导数的data.table(数据在下面给出).
dp
is a data.table containing the data points for which an approximation is sought and ap
is a data.table with the approximated data plus the derivatives (data are given below).
对于每一行,facet_grid()
和scales = "free_y"
已选择一个显示所有数据的刻度.不幸的是,一个面板具有某种离群值",这使得很难在其他面板中看到细节.所以,我想放大".
For each row, facet_grid()
with scales = "free_y"
has choosen a scale which displays all data. Unfortunately, one panel has kind of "outliers" which make it difficult to see details in the other panels. So, I want to "zoom in".
ggplot(ap, aes(x, y)) +
geom_point(data = dp, alpha = 0.2) +
geom_line() +
facet_grid(deriv ~ df, scales = "free_y", labeller = label_both) +
theme_bw() +
coord_cartesian(ylim = c(-200, 50))
在手动选择范围内,第3行面板中的更多详细信息可见.但是,该限制已应用于网格的所有面板.因此,在第1行中,几乎无法区分细节.
With the manually selected range, more details in the panels of row 3 have been made visible. But, the limit has been applied to all panels of the grid. So, in row 1 details hardly can been distinguished.
我正在寻找的是一种将具有特定参数的coord_cartesian()
分别应用于网格的每个单独面板(或成组的面板,例如按行)的方法.例如,之后是否可以操纵ggplot
对象?
What I'm looking for is a way to apply coord_cartesian()
with specific parameters separately to each individual panel (or group of panels, e.g., rowwise) of the grid. For instance, is it possible to manipulate the ggplot
object afterwards?
作为一种解决方法,我们可以创建三个单独的图,然后使用cowplot
软件包将它们合并:
As a workaround, we can create three separate plots and combine them afterwards using the cowplot
package:
g0 <- ggplot(ap[deriv == 0], aes(x, y)) +
geom_point(data = dp, alpha = 0.2) +
geom_line() +
facet_grid(deriv ~ df, scales = "free_y", labeller = label_both) +
theme_bw()
g1 <- ggplot(ap[deriv == 1], aes(x, y)) +
geom_line() +
facet_grid(deriv ~ df, scales = "free_y", labeller = label_both) +
theme_bw() +
coord_cartesian(ylim = c(-50, 50))
g2 <- ggplot(ap[deriv == 2], aes(x, y)) +
geom_line() +
facet_grid(deriv ~ df, scales = "free_y", labeller = label_both) +
theme_bw() +
coord_cartesian(ylim = c(-200, 100))
cowplot::plot_grid(g0, g1, g2, ncol = 1, align = "v")
不幸的是,此解决方案
- 需要编写代码来创建三个单独的图,
- 复制带状图和轴,并添加空格,该空格不可用于显示数据.
我们可以使用facet_wrap()
代替facet_grid()
:
ggplot(ap, aes(x, y)) +
# geom_point(data = dp, alpha = 0.2) + # this line causes error message
geom_line() +
facet_wrap(~ deriv + df, scales = "free_y", labeller = label_both, nrow = 3) +
theme_bw()
现在,每个面板的y轴分别缩放,以显示某些面板的详细信息.不幸的是,我们仍然无法放大"右下角的面板,因为使用coord_cartesian()
会影响所有面板.
Now, the y-axes of every panel are scaled individually exhibiting details of some of the panels. Unfortunately, we still can't "zoom in" into the bottom right panel because using coord_cartesian()
would affect all panels.
此外,
geom_point(data = dp, alpha = 0.2)
奇怪的原因
gList(list(x = 0.5,y = 0.5,width = 1,height = 1,just ="centre",: 在"gList"中仅允许使用"grobs"
Error in gList(list(x = 0.5, y = 0.5, width = 1, height = 1, just = "centre", : only 'grobs' allowed in "gList"
我不得不对此行进行注释,因此不会显示要近似的数据点.
I had to comment this line out, so the the data points which are to be approximated are not displayed.
library(data.table)
# data points
dp <- data.table(
x = c(6.6260, 6.6234, 6.6206, 6.6008, 6.5568, 6.4953, 6.4441, 6.2186,
6.0942, 5.8833, 5.7020, 5.4361, 5.0501, 4.7440, 4.1598, 3.9318,
3.4479, 3.3462, 3.1080, 2.8468, 2.3365, 2.1574, 1.8990, 1.5644,
1.3072, 1.1579, 0.95783, 0.82376, 0.67734, 0.34578, 0.27116, 0.058285),
y = 1:32,
deriv = 0)
# approximated data points and derivatives
ap <- rbindlist(
lapply(seq(2, length(dp$x), length.out = 4),
function(df) {
rbindlist(
lapply(0:2,
function(deriv) {
result <- as.data.table(
predict(smooth.spline(dp$x, dp$y, df = df), deriv = deriv))
result[, c("df", "deriv") := list(df, deriv)]
})
)
})
)
推荐答案
最新答案,但以下黑客只是我突然想到的.会适合您的用例吗?
Late answer, but the following hack just occurred to me. Would it work for your use case?
第1步.创建预期图的替代版本,限制y值的范围,以使scales = "free_y"
为每个构面行提供所需的比例范围.还要创建具有完整数据范围的预期构面图:
Step 1. Create an alternative version of the intended plot, limiting the range of y values such that scales = "free_y"
gives a desired scale range for each facet row. Also create the intended facet plot with the full data range:
library(ggplot2)
library(dplyr)
# alternate plot version with truncated data range
p.alt <- ap %>%
group_by(deriv) %>%
mutate(upper = quantile(y, 0.75),
lower = quantile(y, 0.25),
IQR.multiplier = (upper - lower) * 10) %>%
ungroup() %>%
mutate(is.outlier = y < lower - IQR.multiplier | y > upper + IQR.multiplier) %>%
mutate(y = ifelse(is.outlier, NA, y)) %>%
ggplot(aes(x, y)) +
geom_point(data = dp, alpha = 0.2) +
geom_line() +
facet_grid(deriv ~ df, scales = "free_y", labeller = label_both) +
theme_bw()
# intended plot version with full data range
p <- p.alt %+% ap
第2步.使用ggplot_build()
生成两个ggplot对象的绘图数据.将alt版本的面板参数应用于预期版本:
Step 2. Use ggplot_build()
to generate plot data for both ggplot objects. Apply the panel parameters of the alt version onto the intended version:
p <- ggplot_build(p)
p.alt <- ggplot_build(p.alt)
p$layout$panel_params <- p.alt$layout$panel_params
rm(p.alt)
第3步.根据修改后的地块数据构建所需的地块,绘制结果:
Step 3. Build the intended plot from the modified plot data, & plot the result:
p <- ggplot_gtable(p)
grid::grid.draw(p)
注意:在此示例中,我通过将每个构面行中距上/下四分位点都大于10 * IQR的所有值设置为NA来截断了数据范围.可以用定义异常值的任何其他逻辑来代替.
Note: in this example, I truncated the data range by setting all values more than 10*IQR away from the upper / lower quartile in each facet row as NA. This can be replaced by any other logic for defining outliers.
这篇关于如何将单独的coord_cartesian()应用于“放大".进入facet_grid()的各个面板中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!