关于 r:有没有办法操纵 ggplot 比例中断和标签? | 珊瑚贝

Is there a way of manipulating ggplot scale breaks and labels?


ggplot 通常可以很好地按比例创建合理的中断和标签。

但是,我发现在具有许多方面和可能是 formatter= 语句的情节中,标签往往会变得过于”密集”和叠印,例如在这张图片中:

1
2
3
4
5
6
7
8
9
df <- data.frame(
        fac=rep(LETTERS[1:10], 100),
        x=rnorm(1000)
)

ggplot(df, aes(x=x)) +
  geom_bar(binwidth=0.5) +
  facet_grid(~fac) +
  scale_x_continuous(formatter=”percent”)

enter

我知道我可以通过向 scale_x_continuous.

提供 breaks= 和 scale= 参数来明确指定刻度的中断和标签

但是,我正在处理包含许多问题和十几个交叉中断的调查数据,因此需要找到一种自动执行此操作的方法。

有没有办法告诉 ggplot 自动计算中断和标签,但只需要更少,比如在最小值、最大值和零点处?

编辑:理想情况下,我不想指定最小和最大点,而是以某种方式利用内置的 ggplot 刻度训练,并使用默认计算的刻度限制。


您可以在调用 ggplot 时传入诸如 min() 和 max() 之类的参数来动态指定中断。听起来您将在各种数据中应用此方法,因此您可能需要考虑将其概括为一个函数并弄乱格式,但这种方法应该有效:

1
2
3
4
5
6
ggplot(df, aes(x=x)) +
  geom_bar(binwidth=0.5) +
  facet_grid(~fac) +
  scale_x_continuous(breaks = c(min(df$x), 0, max(df$x))
    , labels = c(paste( 100 * round(min(df$x),2),”%”, sep =””), paste(0,”%”, sep =””), paste( 100 * round(max(df$x),2),”%”, sep =””))
    )

或使用 opts(axis.text.x = theme_text(angle = 90, hjust = 0)) 旋转 x 轴文本以产生类似:

enter

更新

在最新版本的 ggplot2 中,scale_x_continuous 的 breaks 和 labels 参数接受函数,因此可以执行以下操作:

1
2
3
4
5
6
7
8
9
10
11
myBreaks <- function(x){
    breaks <- c(min(x),median(x),max(x))
    names(breaks) <- attr(breaks,”labels”)
    breaks
}

ggplot(df, aes(x=x)) +
  geom_bar(binwidth=0.5) +
  facet_grid(~fac) +
  scale_x_continuous(breaks = myBreaks,labels = percent_format()) +
  opts(axis.text.x = theme_text(angle = 90, hjust = 1,size = 5))

  • @Chase 谢谢。是的,我考虑过这样做,但这并不理想。原因是数据可能是百分比、受访者人数、t-stat 分数或其他。计算最接近的幅度可能是一种选择,但我真正想做的是使用 ggplot 训练的比例,然后隐藏端点之间的标签。换句话说,有时我希望比例的上限为(例如)60%。我希望这是有道理的。
  • @Andrie – 明白了。所以你真正需要的是一个函数,它可以解释 x 轴上显示的数据类型(百分比、计数等)并相应地修改比例,对吧?您可以在列上使用 class() 来帮助告知这一点吗?或者其他一些数据/元数据可以告知您到底在绘制什么?假设您有一些信息来告知格式化的内容和方式,编写一个小函数来生成中断和标签的向量以传递给 scale_x_continuous() 应该不会太难。
  • @Chase我希望有人会提供更通用的方法。例如,在使用刻面和自由音阶时,例如facet_grid(~fac, scales=”free”),每个方面的高断点和低断点通常是不同的。所以我真正想要的是在不指定中断的情况下抑制标签。
  • @Andrie 也许您可以提供一组更新的示例数据来更好地说明您的问题?据我所知,您至少有两个不同的问题。 1. 比例轴的过度绘制,2. 使用相同的代码块在不同的灯光下呈现相同的数据。您可以使用 … + opts(axis.text.x = theme_text(angle = 90, hjust = 0)) 之类的东西来解决过度绘图问题。如果您想超越格式问题,我认为您将不得不编写自己的函数来将参数传递给 labels() 和 breaks()。
  • 1 用于建议更改文本的angular和文本的大小。这将有助于满足我的即时演示需求。
  • 1.5 接受。仅供参考,Hadley Wickham 在另一个论坛中回应说,目前我想做的事情并不容易,但在不久的将来版本中,人们将对中断和刻度线有更多的控制权。


scales 包包含几个 breaks_* 和 label_* 函数,它们返回 ggplot 使用的函数(闭包)。因此,您可以为这些修改输出的package器编写一个package器。

例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
library(ggplot2)

# Compute the list of breaks using original_func,
# then remove any of these that occur in remove_list
remove_breaks <- function(original_func, remove_list = list()) {
  function(x) {
    original_result <- original_func(x)
    original_result[!(original_result %in% remove_list)]
  }
}

# Compute the list of labels using original_func,
# then remove any of these that occur in remove_list
remove_labels <- function(original_func, remove_list = list()) {
  function(x) {
    original_result <- original_func(x)
    replace(original_result, original_result %in% remove_list, ”)
  }
}

# Original plot
ggplot(data.frame(x=c(1,2,3,4,5,6,7,8), y = c(1,4,9,16,25,36,49,64))) + geom_line(aes(x, y)) +
  scale_x_continuous(breaks       = scales::breaks_pretty(9),
                     minor_breaks = scales::breaks_pretty(18),
                     labels       = scales::label_number_auto()) +
  scale_y_continuous(breaks       = scales::breaks_pretty(9),
                     minor_breaks = scales::breaks_pretty(18),
                     labels       = scales::label_number_auto())

# Remove some breaks from the x-axis, and remove some labels from the y-axis
ggplot(data.frame(x=c(1,2,3,4,5,6,7,8), y = c(1,4,9,16,25,36,49,64))) + geom_line(aes(x, y)) +
  scale_x_continuous(breaks       = remove_breaks(scales::breaks_pretty(9), seq(3,6)),
                     minor_breaks = remove_breaks(scales::breaks_pretty(18), seq(3,6,0.5)),
                     labels       = scales::label_number_auto()) +
  scale_y_continuous(breaks       = scales::breaks_pretty(9),
                     minor_breaks = scales::breaks_pretty(18),
                     labels       = remove_labels(scales::label_number_auto(), seq(20, 30)))

当然,使用我简单的 remove_breaks 和 remove_labels 函数,您仍然需要指定要删除的值,但是您可以轻松地将它们修改为删除最大值和最小值,删除指定范围内的任何值等

  • 在注意到问题的年龄有多大之前写了一个答案???。


来源:https://www.codenong.com/5380417/

微信公众号
手机浏览(小程序)

Warning: get_headers(): SSL operation failed with code 1. OpenSSL Error messages: error:14090086:SSL routines:ssl3_get_server_certificate:certificate verify failed in /mydata/web/wwwshanhubei/web/wp-content/themes/shanhuke/single.php on line 57

Warning: get_headers(): Failed to enable crypto in /mydata/web/wwwshanhubei/web/wp-content/themes/shanhuke/single.php on line 57

Warning: get_headers(https://static.shanhubei.com/qrcode/qrcode_viewid_10082.jpg): failed to open stream: operation failed in /mydata/web/wwwshanhubei/web/wp-content/themes/shanhuke/single.php on line 57
0
分享到:
没有账号? 忘记密码?