计算出 ggsave 中最终绘图给定尺寸的面板大小(以显示 geom_dotplot 的计数)

发布于 2025-01-10 01:40:53 字数 1359 浏览 6 评论 0原文

我试图在 x 轴上显示点图的计数,如下所述: 显示点图的 x 轴计数

library(ggplot2)
library(grid)

date = seq(as.Date("2016/1/5"), as.Date("2016/1/12"), "day")
value = c(11,11,12,12,13,14,14,14)
dat =data.frame(date = date, value = value)

### base plot
g <- ggplot(dat, aes(x = value)) + geom_dotplot(binwidth = 0.8) + coord_flip()
g  # output to read parameter

### calculation of width and height of panel
current.vpTree()
seekViewport('panel.3-4-3-4')
real_width <- convertWidth(unit(1,'npc'), 'inch', TRUE)
real_height <- convertHeight(unit(1,'npc'), 'inch', TRUE)

### calculation of other values
height_coordinate_range <-diff(ggplot_build(g)$layout$panel_params[[1]]$y.range)
real_binwidth <- real_height / height_coordinate_range * 0.8  # 0.8 is the argument binwidth
num_balls <- real_width / 1.1 / real_binwidth  # the number of stacked balls. 1.1 is expanding value.

g + ylim(0, num_balls) 

但是,它在我看来,real_width指的是面板的宽度,而不是整个图。当我使用时,这会导致计数刻度和点之间的不对齐:

ggsave(g, 
       filename = "g.png", 
       path = getwd(),
       device = "png",
       height = real_height,
       width = real_width,
       units = "cm")

假设我想要一个 6cm x 6cm 的绘图,我如何找出面板的尺寸,以便我可以使用面板尺寸来计算 num_balls ?

I'm trying to show the count for dotplot on the x-axis as outlined here:
showing count on x-axis for dot plot

library(ggplot2)
library(grid)

date = seq(as.Date("2016/1/5"), as.Date("2016/1/12"), "day")
value = c(11,11,12,12,13,14,14,14)
dat =data.frame(date = date, value = value)

### base plot
g <- ggplot(dat, aes(x = value)) + geom_dotplot(binwidth = 0.8) + coord_flip()
g  # output to read parameter

### calculation of width and height of panel
current.vpTree()
seekViewport('panel.3-4-3-4')
real_width <- convertWidth(unit(1,'npc'), 'inch', TRUE)
real_height <- convertHeight(unit(1,'npc'), 'inch', TRUE)

### calculation of other values
height_coordinate_range <-diff(ggplot_build(g)$layout$panel_params[[1]]$y.range)
real_binwidth <- real_height / height_coordinate_range * 0.8  # 0.8 is the argument binwidth
num_balls <- real_width / 1.1 / real_binwidth  # the number of stacked balls. 1.1 is expanding value.

g + ylim(0, num_balls) 

However, it seems to me that real_width refers to width of the panel, not the whole plot. This leads to a misalignment between count ticks and dots when I use:

ggsave(g, 
       filename = "g.png", 
       path = getwd(),
       device = "png",
       height = real_height,
       width = real_width,
       units = "cm")

Given I want a plot that is 6cm x 6cm, how can i find out the dimensions of the panel, so that I can use the panel dimensions to calculate num_balls?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

猛虎独行 2025-01-17 01:40:53

这个故事的寓意是:在绘制情节之前,您无法准确知道面板的尺寸。但是,您可以通过从输出尺寸中减去绘图装饰的尺寸来近似它。这种方法忽略了现实中图形设备可以具有影响文本真实大小的“分辨率”/“缩放”参数。这里的原因是,由于面板是“空”单位,因此在减去每个非空单位后,它们会适应输出维度的剩余部分。

library(ggplot2)
library(grid)

dat =data.frame(
  date = seq(as.Date("2016/1/5"), as.Date("2016/1/12"), "day"), 
  value = c(11,11,12,12,13,14,14,14)
)

g <- ggplot(dat, aes(x = value)) + geom_dotplot(binwidth = 0.8) + coord_flip()

output_width <- unit(6, "cm")
output_height <- unit(6, "cm")

# Convert plot to gtable
gt <- ggplotGrob(g)

# Find panel
is_panel <- grep("panel", gt$layout$name)
panel_location <- gt$layout[is_panel,]

# Note: panel width / heights are 'null' units
gt$widths[panel_location$l]
#> [1] 1null
gt$heights[panel_location$t]
#> [1] 1null

# Get widths/heights of everything except the panel
width  <- gt$widths[-panel_location$l]
height <- gt$heights[-panel_location$t]

# Calculate as output size - size of plot decoration
panel_height <- output_height - sum(height)
panel_width  <- output_width - sum(width)

convertUnit(panel_height, "cm")
#> [1] 4.6283951674277cm
convertUnit(panel_width, "cm")
#> [1] 4.57547850076103cm

reprex 包 (v2.0.1) 于 2022 年 2 月 24 日创建

有一些方法可以修复面板的尺寸,使事情变得更容易,但这不是问题所在。

The moral of the story is: you can't know the panel size exactly until the plot is being drawn. However, you can approximate it by subtracting the dimensions of plot decoration from the output dimension. This approach ignores that in reality, graphics devices can have a 'resolution'/'scaling' parameter that effects the true size of the text. The reasoning here is that since panels are 'null' units, they adapt to whatever is left of the output dimension, after every non-null units have been subtracted.

library(ggplot2)
library(grid)

dat =data.frame(
  date = seq(as.Date("2016/1/5"), as.Date("2016/1/12"), "day"), 
  value = c(11,11,12,12,13,14,14,14)
)

g <- ggplot(dat, aes(x = value)) + geom_dotplot(binwidth = 0.8) + coord_flip()

output_width <- unit(6, "cm")
output_height <- unit(6, "cm")

# Convert plot to gtable
gt <- ggplotGrob(g)

# Find panel
is_panel <- grep("panel", gt$layout$name)
panel_location <- gt$layout[is_panel,]

# Note: panel width / heights are 'null' units
gt$widths[panel_location$l]
#> [1] 1null
gt$heights[panel_location$t]
#> [1] 1null

# Get widths/heights of everything except the panel
width  <- gt$widths[-panel_location$l]
height <- gt$heights[-panel_location$t]

# Calculate as output size - size of plot decoration
panel_height <- output_height - sum(height)
panel_width  <- output_width - sum(width)

convertUnit(panel_height, "cm")
#> [1] 4.6283951674277cm
convertUnit(panel_width, "cm")
#> [1] 4.57547850076103cm

Created on 2022-02-24 by the reprex package (v2.0.1)

There are ways to fix the dimensions of a panel that would make things easier, but that wasn't the question.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文