如何将单独的coord_cartesian()应用于“放大".进入facet_grid()的各个面板中? [英] How to apply separate coord_cartesian() to "zoom in" into individual panels of a facet_grid()?

查看:90
本文介绍了如何将单独的coord_cartesian()应用于“放大".进入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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆