使用ggplot2以粗体对齐各个轴标签 [英] Justify individual axis labels in bold using ggplot2

查看:343
本文介绍了使用ggplot2以粗体对齐各个轴标签的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

从这个问题和解决方案改编的问题:



好的,我从上面的问题+答案中采用了函数来生成一个理由向量:

 #修改以控制理由
colorado2< - 函数(src,boulder){
i f(!is.factor(src))src < - factor(src)
src_levels < - levels(src)
brave < - boulder%in%src_levels
if(all (brave)){
b_pos < - purrr :: map_int(boulder,〜which(。== src_levels))
b_vec < - rep(0.2,length(src_levels))
b_vec [b_pos] < - 0.9
b_vec
} else {
stop(boulder的所有元素都必须在src中)



#使用修饰
ggplot(xx,aes(x = VALUE,y = CLONE,fill = YEAR))+
重绘绘图geom_bar(stat =identity,position =dodge)+
facet_wrap(〜TREAT)+
theme(axis.text.y = element_text(hjust = colorado2(xx $ CLONE,c(A,B,E ))))

我得到这个不幸的混乱:



这些标签在我想要的方向上是合理的 - 但由于我无法理解的原因占用了太多的情节弄清楚。我如何解决这个问题?

解决方案

我做了一些挖掘工作。问题在于ggplot如何设置y轴grob的grob宽度。它假设 hjust 在所有标签中都是相同的。我们可以通过对grob树的一些黑客手段来解决这个问题。下面的代码已经用ggplot2的开发版本进行了测试,可能无法像使用当前发布的版本一样编写。

首先,一个简单的可重复的例子:

  p < -  ggplot(mpg,aes(manufacturer,hwy))+ geom_boxplot()+ coord_flip()+ 
theme .text.y = element_text(hjust = c(rep(1,10),rep(0,5))))
p#不起作用



问题在于grob的宽度轴grob被设置为整个绘图区域。但我们可以手动进入并修复宽度。不幸的是,我们必须在多个位置修复它:

 #获得y标签的向量作为字符串
ylabels< ; - as.character(唯一(mpg $制造商))

库(网格)
g< - ggplotGrob(p)

#我们需要修复在grob树的不同位置上的grob宽度
g $ grobs [[3]] $ children [[2]] $ widths [1]< - max(stringWidth(ylabels))
g $ grobs [ 3]] $ width< - sum(grobWidth(g $ grobs [[3]] $ children [[1]]),grobWidth(g $ grobs [[3]] $ children [[2]]))
g $ widths [3]< - g $ grobs [[3]] $ width

#绘制绘图
grid.newpage()
grid.draw(g )



ggplot2的轴绘图代码可能会被修改来计算宽度,就像我从一开始那样计算宽度,然后这个问题就会消失。


Question adapted from this question and solution: Highlighting individual axis labels in bold using ggplot2

I would like to selectively justify the horizontal axes labels depending on meeting a criteria. So borrowing from the above question and answer I've set up an example:

require(ggplot2)
require(dplyr)
set.seed(36)
xx<-data.frame(YEAR=rep(c("X", "Y"), each=20),
           CLONE=rep(c("A", "B", "C", "D", "E"), each=4, 2),
           TREAT=rep(c("T1", "T2", "T3", "C"), 10),
           VALUE=sample(c(1:10), 40, replace=T))

# Simple plot with factors on y axis
ggplot(xx, aes(x = VALUE, y=CLONE, fill=YEAR)) + 
    geom_bar(stat="identity", position="dodge") +
    facet_wrap(~TREAT)

Ok so I adopted function from the above question + answer to generate a vector of justifications:

# Modify to control justification
colorado2 <- function(src, boulder) {
    if (!is.factor(src)) src <- factor(src)                   
    src_levels <- levels(src)                                 
    brave <- boulder %in% src_levels                         
    if (all(brave)) {                                         
        b_pos <- purrr::map_int(boulder, ~which(.==src_levels)) 
        b_vec <- rep(0.2, length(src_levels))               
        b_vec[b_pos] <- 0.9                                 
        b_vec                                                  
    } else {
        stop("All elements of 'boulder' must be in src")
    }
}

# Redraw the plot with modifcation
ggplot(xx, aes(x = VALUE, y=CLONE, fill=YEAR)) + 
    geom_bar(stat="identity", position="dodge") +
    facet_wrap(~TREAT) +
    theme(axis.text.y=element_text(hjust=colorado2(xx$CLONE, c("A", "B", "E"))))

I'm getting this unfortunate mess:

The labels are justified in the direction I want - but taking up far too much of the plot for reasons I cannot figure out. How do I fix this ?

解决方案

I did some digging. The problem is with how ggplot sets the grob width of the y axis grob. It assumes that hjust is the same across all labels. We can fix this with some hacking of the grob tree. The following code was tested with the development version of ggplot2 and may not work as written with the currently released version.

First, a simple reproducible example:

p <- ggplot(mpg, aes(manufacturer, hwy)) + geom_boxplot() + coord_flip() + 
  theme(axis.text.y = element_text(hjust = c(rep(1, 10), rep(0, 5))))
p # doesn't work

The problem is that the grob width of the axis grob gets set to the entire plot area. But we can manually go in and fix the width. Unfortunately we have to fix it in multiple locations:

# get a vector of the y labels as strings
ylabels <- as.character(unique(mpg$manufacturer))

library(grid)
g <- ggplotGrob(p)

# we need to fix the grob widths at various locations in the grob tree
g$grobs[[3]]$children[[2]]$widths[1] <- max(stringWidth(ylabels))
g$grobs[[3]]$width <- sum(grobWidth(g$grobs[[3]]$children[[1]]), grobWidth(g$grobs[[3]]$children[[2]]))
g$widths[3] <- g$grobs[[3]]$width

# draw the plot
grid.newpage()
grid.draw(g)

The axis-drawing code of ggplot2 could probably be modified to calculate width like I did here from the outset, and then the problem would disappear.

这篇关于使用ggplot2以粗体对齐各个轴标签的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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