2017-04-07 104 views
1

我的目标是做一个简单的柱状图中ggplot2看起来像下图(在Excel中制作): enter image description here展开Y比例,但Y轴线的极限高度

什么我的发现是,与这样的示例数据(其中一个百分比值非常接近100%),我在ggplot2中绘制这些数据的选项留下了一些不足之处。特别是,我还没有找到一种方法,使下面两个简单的事情发生了一起:

1)使y轴行尾在100%

2)使百分比每个栏上的标签都可见

为了解决这个问题,我尝试过对scale_y_continuous()尝试不同的参数,但是还没有找到同时满足上述两个目标的方法。你可以在下面的示例图和代码中看到它。

我的问题是:如何扩展y比例,以便每个数据点上的百分比标签都可见,但y轴线以100%结束?

library(dplyr) 
library(ggplot2) 
library(scales) 


example_df <- data_frame(Label = c("A", "B"), 
         Percent = c(0.5, 0.99)) 

example_plot <- example_df %>% 
     ggplot(aes(x = Label, y = Percent)) + 
     geom_bar(stat = "identity", 
        fill = "dodgerblue4", width = .6) + 
     geom_text(aes(label = percent(Percent)), 
        size = 3, vjust = -0.5) + 
     scale_x_discrete(NULL, expand = c(0, .5)) + 
     theme_classic() 

情节与期望的y轴线,但不可见的标签在酒吧

这是当我设置上scale_y_continuous()c(0,1)极限会发生什么:

enter image description here

example_plot + 
    scale_y_continuous(NULL, limits = c(0, 1.0), breaks = seq(0, 1, .2), 
         labels = function(x) scales::percent(x), 
         expand = c(0, 0)) + 
    labs(title = "Y axis line looks perfect, but the label over the bar is off") 

y轴线太长,但可看到标签超过条形图

这里是当我设置上scale_y_continuous()c(0,1.05)极限会发生什么:

enter image description here

example_plot + 
    scale_y_continuous(NULL, limits = c(0, 1.05), breaks = seq(0, 1, .2), 
         labels = function(x) scales::percent(x), 
         expand = c(0, 0)) + 
    labs(title = "Y axis line is too long, but the label over the bar is visible") 

回答

1

您可以删除定期轴心线,然后用geom_segment创建一个新的:

example_df %>% 
ggplot(aes(x = Label, y = Percent)) + 
    geom_bar(stat = "identity", fill = "dodgerblue4", width = .6) + 
    geom_text(aes(label = percent(Percent)), size = 3, vjust = -0.5) + 
    scale_x_discrete("", expand = c(0, .5)) + 
    scale_y_continuous("", breaks = seq(0, 1, .2), labels = percent, limits=c(0,1.05), 
        expand=c(0,0)) + 
    theme_classic() + 
    theme(axis.line.y=element_blank()) + 
    geom_segment(x=.5025, xend=0.5025, y=0, yend=1.002) 

enter image description here

要回应你的评论:即使它在剧情区域之外,99%的标签仍在绘制,但它被“剪辑”,这意味着绘图区域外的绘图元素被屏蔽。因此,另一种选择,还是哈克,但比我原来的答复少哈克,是这样出现的标签关闭剪裁:

library(grid) 

p = example_df %>% 
    ggplot(aes(x = Label, y = Percent)) + 
    geom_bar(stat = "identity", fill = "dodgerblue4", width = .6) + 
    geom_text(aes(label = percent(Percent)), size = 3, vjust = -0.5) + 
    scale_x_discrete("", expand = c(0, .5)) + 
    scale_y_continuous("", breaks = seq(0, 1, .2), labels = percent, limits=c(0,1), 
         expand=c(0,0)) + 
    theme_classic() + 
    theme(plot.margin=unit(c(10,0,0,0),'pt')) 

# Turn off clipping 
pg <- ggplot_gtable(ggplot_build(p)) 
pg$layout$clip[pg$layout$name=="panel"] <- "off" 
grid.draw(pg) 

enter image description here

+0

这将产生所希望的描绘(并且是一个很好的答案) ,但不得不使用'geom_segment()'是一种黑客解决方案。看起来这是'ggplot2'这样一个常见的足够用例,应该有一些方法可以用'scale_y_continuous'的参数来解决问题。 – bschneidr

+0

这绝对是一个黑客攻击,但我不知道用标准的'scales'或'coord'函数做这件事的方法。另一种选择是将数字标签放在条的中间。无论如何,我更喜欢这种方法,因为酒吧上方的标签会从酒吧高度的视觉尺度上分散一点。 – eipi10

+0

禁用裁剪的方法绝对不是黑客攻击。我想知道@hadley是否可以接受一个函数的pull请求,这个函数可以更简单地禁用裁剪,像'toggle_panel_clipping(my_plot,“off”)一样工作' – bschneidr