r - 如何删除geom_col周围的ggplot2背景和裁剪边距
问题描述
我想使用堆积柱形图制作“时间线”。我想要做的是删除所有背景,所以我只有一个酒吧,没有别的。我被图表的白色背景困住了。
这是一个最小的例子:
mytheme <- theme(
axis.title.x=element_blank(),
axis.text.x=element_blank(),
axis.ticks.x=element_blank(),
axis.title.y=element_blank(),
axis.text.y=element_blank(),
axis.ticks.y=element_blank(),
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
#panel.background = element_blank()
)
Name <- c("One", "Two", "Three", "Four")
value <- c(2, 5, 7, 8)
df <- data.frame(Name, value)
ggplot(df)+
aes(x= "Name", y = value, fill = Name) +
geom_col(width = .1, show.legend = FALSE) +
xlab("") + ylab("") +
coord_flip() +
mytheme
(我已经注释掉panel.background
只是为了显示背景的范围。我想“裁剪”那个白色背景,所以我只有栏或栏周围只有一点空间。请帮助。
更新
在@Gregor 的建议下,我修改了代码ggplot
如下:
ggplot(df)+
aes(x= "Name", y = value, fill = Name) +
geom_col(width = .1, show.legend = FALSE) +
xlab("") + ylab("") +
coord_flip(expand = FALSE) +
mytheme
结果是一个非常宽的条(因为我使用了 coord_flip,所以页面很高):
我现在需要做的就是降低高度(如图所示),使其更像我原来的酒吧。我该如何改变呢?
解决方案
我终于找到了一个简单的解决方案。当我使用时R Markdown
,我使用了:
```{r, ..., fig.width=4, fig.height=.3}
在嵌入图的序言中。不是最好的解决方案,但它有效。谢谢大家。
解决方案
这是一个非常有趣的问题。这是解决此问题的一种方法:与其使用垂直堆叠的条形图然后水平翻转它,我们可以简单地创建一个“常规”条形图,其中条形彼此相邻并且具有相同的高度,但每个条形图都有一个可变宽度,等于您想要的时间间隔的持续时间。我们可以使用coord_fixed(expand = FALSE)
.
如果我们直接将 x 轴位置指定为 可能是最好的ggplot()
,这样我们就可以使用它们来放置我们的标签(稍后会详细介绍) - 以下是如何定位时间轴的间隔:
令X i表示从原点到每个时间间隔i的中心的距离(沿 x 轴)。对于每个区间i,X i是先前时间区间X 0 : X i - 1的长度之和,加上X i长度的一半。我们可以通过添加一个使用滞后累积和的列来让 R 自动为我们生成这些值,如下所示。
我留下了panel.background = element_blank()
注释,以便您可以确认我们确实获得了“只是时间线”,没有背景。
代码:
library("tidyverse")
mytheme <- theme(
axis.title.x=element_blank(),
axis.text.x=element_blank(),
axis.ticks.x=element_blank(),
axis.title.y=element_blank(),
axis.text.y=element_blank(),
axis.ticks.y=element_blank(),
panel.grid.major = element_blank(),
panel.grid.minor = element_blank(),
#panel.background = element_blank()
)
Name <- c("One", "Two", "Three", "Four")
Value <- c(2, 5, 7, 8)
df <- data.frame(Name, Value) %>%
mutate(Name = factor(Name, levels = Name),
xPos = cumsum(lag(Value, default = 0)) + Value/2) # calculate interval position
ggplot(data = df, aes(x = xPos, y = 1, width = Value, fill = Name)) +
geom_col(position = "identity",
show.legend = FALSE) +
geom_text(aes(label = Name),
position = position_fill(vjust = 0.5)) +
coord_fixed(expand = FALSE) + # crop background around geom_col()
mytheme
输出:
为什么有效:
从ggplot2
3.1.0 版本开始,我们最初陷入了两难境地:如果我们选择使用coord_flip()
,我们可以获得水平时间线,但我们不能(轻松)调整绘图区域的大小以达到我们想要的尺寸。如果我们改为使用coord_fixed(expand = FALSE)
,我们将获得所需的绘图边距,但我们不能轻松地制作水平“堆叠”条形,因为coord_fixed()
与coord_flip()
.
有一个有趣的参数position_dodge2()
,你可以使用 withgeom_col()
来将可变宽度的条彼此相邻放置。如果您设置padding = 0
,您可以获得与您在上面看到的非常相似的图,但是每个间隔的实际“x 坐标”将从每个条的左边缘开始,而不是中心。
这使得文本标签的居中变得非常困难,因为我们需要根据每个间隔的宽度来调整它们的位置,但是ggplot2
像这样的选项position_nudge()
只允许我们以某个恒定的量调整所有标签。因此,我们直接指定每个时间间隔的中心。希望随着ggplot2
不断改进,我们将看到诸如position_nudge()
获得附加功能之类的选项以更轻松地处理此问题!
推荐阅读
- json - 为什么将数组编码为 json 格式会产生 json 对象?
- java - 在请求权限之前关闭 Android 应用程序?怎么解决?
- c# - 如何使用 C# 在 MouseDown 后沿任何方向绘制矩形?
- python - 与 super() 调用有点混淆
- database - 如何在这个集群(Ubuntu)中创建一个postgresql(版本10)集群和数据库?
- cmake - mingw 在 Windows 上找不到 libpng 的 png.h
- java - android 应用内更新 API 未按预期工作
- java - 写入和追加到 .dat 文件
- github - git push -u origin master 错误用户名或密码错误
- node.js - 如何查看当前正在使用哪个 .npmrc 文件