Метки оси вращения и расстояния в ggplot2

У меня есть график, на котором ось x - это фактор, метки которого длинные. Хотя, вероятно, это не идеальная визуализация, сейчас я хотел бы просто повернуть эти метки, чтобы они были вертикальными. Я понял эту часть с помощью приведенного ниже кода, но, как вы можете видеть, метки не полностью видны.

data(diamonds)
diamonds$cut <- paste("Super Dee-Duper",as.character(diamonds$cut))
q <- qplot(cut,carat,data=diamonds,geom="boxplot")
q + opts(axis.text.x=theme_text(angle=-90))

введите описание изображения здесь


person Christopher DuBois    schedule 25.08.2009    source источник
comment
Поскольку ggplot 3.3.0 сейчас отсутствует, ИМО, принятый ответ должен быть изменен на jan-glx s one   -  person akraf    schedule 13.10.2020


Ответы (8)


Измените последнюю строку на

q + theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1))

По умолчанию оси выравниваются по центру текста даже при повороте. Когда вы поворачиваете +/- 90 градусов, вы обычно хотите, чтобы он был выровнен по краю:

alt text

Изображение выше взято из этого сообщения в блоге.

person Jonathan Chang    schedule 25.08.2009
comment
В последней версии ggplot2 команда будет выглядеть так: q + theme(axis.text.x=element_text(angle = -90, hjust = 0)) - person rnorberg; 28.09.2012
comment
Тем, для кого hjust ведет себя не так, как описано здесь, попробуйте theme(axis.text.x=element_text(angle = 90, vjust = 0.5)). Что касается ggplot2 0.9.3.1, похоже, это решение. - person lilster; 12.08.2013
comment
На самом деле, мне пришлось объединить два решения выше, чтобы получить правильно выровненные метки: q + theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1)) - person jupp0r; 25.12.2013
comment
@ jupp0r правильно. theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1)) ТОЛЬКО РАБОТАЕТ В НАСТОЯЩЕЕ ВРЕМЯ. - person ; 03.03.2014
comment
если вам нужны этикетки с поворотом на 45 ° (легче читать) theme(axis.text.x = element_text(angle = 45, vjust = 1, hjust=1)) дает хорошие результаты - person jan-glx; 10.05.2015
comment
В моем случае у меня vjust был 0,3, чтобы он действительно выглядел по центру q + theme(axis.text.x = element_text(angle = 90, vjust = 0.3, hjust=1)). Я использую ezplot из пакета ez, и использование vjust = 0.5 дало слегка искаженный результат - person toto_tico; 28.10.2015
comment
Если кто-то его ищет, он также работает с qplot - person Filippo Mazza; 27.04.2017
comment
Как я могу его использовать, когда я использую опцию geom_bar (stat = identity, position = dodge)? Странно то, что он не вращает этикетки - person skan; 26.09.2017
comment
В настоящее время вы можете просто использовать guides(x = guide_axis(angle = 90)) + . (см. также мой ответ ниже) - person jan-glx; 12.08.2020
comment
Для большей ясности при использовании hjust и vjust см. Этот отличный пост: stackoverflow.com/questions/7263849/ - person jlsecrest; 04.07.2021

Используйте coord_flip()

data(diamonds)
diamonds$cut <- paste("Super Dee-Duper",as.character(diamonds$cut))

qplot(cut, carat, data = diamonds, geom = "boxplot") +
  coord_flip()

введите описание изображения здесь


Добавить str_wrap()

# wrap text to no more than 15 spaces
library(stringr)
diamonds$cut2 <- str_wrap(diamonds$cut, width = 15)
qplot(cut2, carat, data = diamonds, geom = "boxplot") +
  coord_flip()

введите описание изображения здесь


В главе 3.9 R для науки о данных , Уикхэм и Гролемунд отвечают именно на этот вопрос:

coord_flip() переключает оси x и y. Это полезно (например), если вам нужны горизонтальные блочные диаграммы. Это также полезно для длинных этикеток: их сложно уместить без перекрытия по оси абсцисс.

person Rich Pauloo    schedule 01.08.2017

Чтобы текст меток галочки был полностью видим и читался в том же направлении, что и метка оси Y, измените последнюю строку на

q + theme(axis.text.x=element_text(angle=90, hjust=1))
person e3bo    schedule 20.12.2010

ggplot 3.3.0 исправляет это, предоставляя guide_axis(angle = 90) (как guide аргумент в scale_.. или как x аргумент для guides):

library(ggplot2)
data(diamonds)
diamonds$cut <- paste("Super Dee-Duper", as.character(diamonds$cut))

ggplot(diamonds, aes(cut, carat)) +
  geom_boxplot() +
  scale_x_discrete(guide = guide_axis(angle = 90)) +
  # ... or, equivalently:
  # guides(x =  guide_axis(angle = 90)) +
  NULL

Из документации по аргументу angle:

По сравнению с установкой угла в theme () / element_text (), здесь также используются некоторые эвристики для автоматического выбора hjust и vjust, которые вы, вероятно, захотите.


В качестве альтернативы он также предоставляет guide_axis(n.dodge = 2) (как guide аргумент для scale_.. или как x аргумент для guides), чтобы преодолеть проблему чрезмерного вывода на график путем уклонения от меток по вертикали. В этом случае это работает неплохо:

library(ggplot2)
data(diamonds)
diamonds$cut <- paste("Super Dee-Duper",as.character(diamonds$cut))

ggplot(diamonds, aes(cut, carat)) + 
  geom_boxplot() +
  scale_x_discrete(guide = guide_axis(n.dodge = 2)) +
  NULL

person jan-glx    schedule 12.03.2020
comment
Хотя мне здесь нравится решение для уклонения, стоит отметить, что guide_axis(angle=90) выбирает правильные значения vjust и hjust, что решает проблему в OP. - person eipi10; 11.08.2020
comment
@ eipi10 Спасибо, я не знал и добавил это к ответу! - person jan-glx; 12.08.2020
comment
Хороший трюк: добавление NULL в конце. - person zx8754; 14.01.2021

Я хотел бы предложить альтернативное решение, надежное решение, подобное тому, что я собираюсь предложить, требовалось в последней версии ggtern, так как появилась функция поворота холста.

По сути, вам нужно определить относительные положения с помощью тригонометрии, создав функцию, которая возвращает объект element_text, заданный угол (то есть градусы) и информацию о позиционировании (то есть одно из значений x, y, сверху или справа).

#Load Required Libraries
library(ggplot2)
library(gridExtra)

#Build Function to Return Element Text Object
rotatedAxisElementText = function(angle,position='x'){
  angle     = angle[1]; 
  position  = position[1]
  positions = list(x=0,y=90,top=180,right=270)
  if(!position %in% names(positions))
    stop(sprintf("'position' must be one of [%s]",paste(names(positions),collapse=", ")),call.=FALSE)
  if(!is.numeric(angle))
    stop("'angle' must be numeric",call.=FALSE)
  rads  = (angle - positions[[ position ]])*pi/180
  hjust = 0.5*(1 - sin(rads))
  vjust = 0.5*(1 + cos(rads))
  element_text(angle=angle,vjust=vjust,hjust=hjust)
}

Честно говоря, на мой взгляд, я считаю, что параметр «auto» должен быть доступен в ggplot2 для аргументов hjust и vjust, в любом случае, при указании угла, давайте продемонстрируем, как это работает.

#Demonstrate Usage for a Variety of Rotations
df    = data.frame(x=0.5,y=0.5)
plots = lapply(seq(0,90,length.out=4),function(a){
  ggplot(df,aes(x,y)) + 
    geom_point() + 
    theme(axis.text.x = rotatedAxisElementText(a,'x'),
          axis.text.y = rotatedAxisElementText(a,'y')) +
    labs(title = sprintf("Rotated %s",a))
})
grid.arrange(grobs=plots)

Что дает следующее:

Пример

person Nicholas Hamilton    schedule 02.05.2016
comment
Я не получаю тех же результатов, для меня текст оси никогда не корректируется с помощью вашего автоматического метода. Однако использование rads = (-angle - positions[[ position ]])*pi/180 привело к лучшим местам размещения. Обратите внимание на дополнительный знак минус перед углом. В любом случае спасибо за код :) - person asachet; 26.08.2016
comment
Получите идею! Я хотел адаптировать вашу функцию, чтобы иметь возможность запускать ее с любыми параметрами element_text(). Поэтому я добавил параметр в функцию с именем element_text_params = list(), заменил последнюю строку в вашей функции на element_text_params <- c(element_text_params, list(angle = angle, vjust = vjust, hjust = hjust)) и вернул return(do.call(element_text, element_text_params)). Таким образом, я могу вызвать вашу функцию как rotatedAxisElementText(45, "y", element_text_params = list("size" = 10, "face" = "bold") - person doRemy; 14.07.2021

Пакет ggpubr предлагает ярлык, который по умолчанию выполняет правильные действия (выравнивание текста по правому краю, текстовое поле с выравниванием по центру для отметки):

library(ggplot2)
diamonds$cut <- paste("Super Dee-Duper", as.character(diamonds$cut))
q <- qplot(cut, carat, data = diamonds, geom = "boxplot")
q + ggpubr::rotate_x_text()

Создано 6 ноября 2018 г. пакетом REPEX (v0.2.1)

Найдено с помощью поиска GitHub по соответствующим именам аргументов: https://github.com/search?l=R&q=element_text+angle+90+vjust+org%3Acran&type=Code

person krlmlr    schedule 06.11.2018

УСТАРЕЛО - см. этот ответ для более простого подхода.


Чтобы получить читаемые метки x без дополнительных зависимостей, вы хотите использовать:

  ... +
  theme(axis.text.x = element_text(angle = 90, hjust = 1, vjust = 0.5)) +
  ...

При этом метки-метки поворачиваются на 90 ° против часовой стрелки и выравниваются по вертикали на концах (hjust = 1) и их центры по горизонтали с соответствующей меткой-меткой (vjust = 0.5).

Полный пример:

library(ggplot2)
data(diamonds)
diamonds$cut <- paste("Super Dee-Duper",as.character(diamonds$cut))
q <- qplot(cut,carat,data=diamonds,geom="boxplot")
q + theme(axis.text.x = element_text(angle = 90, hjust = 1, vjust = 0.5))


Обратите внимание, что параметры выравнивания по вертикали / горизонтали _5 _ / _ 6_ из element_text относятся к тексту. Следовательно, vjust отвечает за горизонтальное выравнивание.

Без vjust = 0.5 это выглядело бы так:

q + theme(axis.text.x = element_text(angle = 90, hjust = 1))

Без hjust = 1 это выглядело бы так:

q + theme(axis.text.x = element_text(angle = 90, vjust = 0.5))

Если по какой-то (проводной) причине вы хотите повернуть метки на 90 ° по часовой стрелке (чтобы их можно было читать слева), вам нужно будет использовать: q + theme(axis.text.x = element_text(angle = -90, vjust = 0.5, hjust = -1)).

Все это уже обсуждалось в комментариях к этому ответу, но я возвращаюсь к этому вопросу так часто, что хочу ответ, из которого я могу просто скопировать, не читая комментариев.

person jan-glx    schedule 11.03.2020

Альтернативой coord_flip() является использование пакета ggstance. Преимущество состоит в том, что это упрощает объединение графиков с графиками других типов, и вы можете, что, возможно, более важно, установить фиксированные коэффициенты масштабирования для вашей системы координат.

library(ggplot2)
library(ggstance)

diamonds$cut <- paste("Super Dee-Duper", as.character(diamonds$cut))

ggplot(data=diamonds, aes(carat, cut)) + geom_boxploth()

Создано 11 марта 2020 г. пакетом REPEX (v0.3.0)

person tjebo    schedule 11.03.2020