axis.break и ggplot2 или gap.plot? сюжет может быть слишком сложным

Я создал сюжет с помощью ggplot2. Речь идет о содержании молочного белка. У меня две группы и 4 процедуры. Я хочу показать взаимодействие между группой и лечением, средними значениями и погрешностями. Содержание белка начинается от 2,6%. Теперь моя ось Y начинается там без зазора, но мой руководитель хочет, чтобы он был. Я попробовал axis.break() из библиотеки plotrix, но ничего не произошло. Я пытался восстановить графику с помощью gap.plot, но у меня ничего не получилось, но я должен признать, что я не R-герой.

Вот код моей графики:

Protein<-ggplot(data=D, aes(x=treat, y=Prot,group=group, shape=group))+
  geom_line(aes(linetype=group), size=1, position=position_dodge(0.2))+
  geom_point(size=3, position=position_dodge(0.2))+
  geom_errorbar(aes(ymin=Prot-Prot_SD,ymax=Prot+Prot_SD), width=.2,      
position=position_dodge(0.2))+ 
  scale_shape_discrete(name='group\n', labels=c('1\n(n =   
22,19,16,20)\n','2\n(n = 15,12,14,12)'))+
  scale_linetype_discrete(name="group\n", labels=c('control\n(n =   
22,19,16,20)\n','free-contact\n(n = 15,12,14,12)'))+
  scale_x_discrete(labels=c('0', '1', '2', '3'))+
  labs(x='\ntreatment', y='protein content (%)\n')
ProtStar<-Protein+annotate("text", x=c(1,2,3,4), y=c(3.25,3.25,3.25,3.25),   
label=c("Aa","Aa","Ab","Ba"), size=4)
plot(ProtStar)

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

Было бы здорово, если бы у вас были полезные предложения. Большое спасибо!


person Z.Kipp    schedule 25.09.2017    source источник
comment
Возможный дубликат Break Y-Axis в ggplot2   -  person pogibas    schedule 25.09.2017
comment
Вы можете опубликовать dput(D)?   -  person Brian    schedule 25.09.2017


Ответы (1)


TL;DR: посмотрите вниз.

Рассмотрим эти цифры:

ggplot(iris, aes(Species, Sepal.Length)) + geom_boxplot() + 
  theme_classic()

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

Это ваш основной сюжет. Теперь вы должны рассмотреть ось Y.


ggplot(iris, aes(Species, Sepal.Length)) + geom_boxplot() + 
  theme_classic() +
  scale_y_continuous(limits = c(0,NA), expand = c(0,0))

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

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

Это также сужает пояснительный диапазон оси Y, так что разница между наблюдениями становится меньше. Если это то, что вы хотите подчеркнуть, это может быть хорошо. Но если естественный диапазон некоторых данных узок, включение нуля (и возникающего в результате пустого места) вводит в заблуждение. Например, если молочный белок всегда находится в пределах от 2,6% до 2,7%, то нулевое значение не является истинным нижним пределом для данных, но так же невозможно, как и -50%.


ggplot(iris, aes(Species, Sepal.Length)) + geom_boxplot() + 
  theme_classic() +
  scale_y_continuous(limits = c(0,NA), expand = c(0,0)) + 
  theme(axis.line.y = element_blank()) +
  annotate(geom = "segment", x = -Inf, xend = -Inf, y = -Inf, yend = Inf) 

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

Есть много причин не включать сломанную ось Y. Многие считают неэтичным или вводящим в заблуждение включение одного в диапазоны данных. Но этот конкретный случай находится на внешнем пределе, за пределами фактических данных. Я думаю, что правила могут быть изогнуты немного для этого.

Первый шаг — удалить автоматическую линию оси Y и нарисовать ее «вручную» с помощью annotate. Обратите внимание, что фигура выглядит идентично предыдущей. Если в выбранной вами теме используется много разных размеров, у вас будут плохие времена.


ggplot(iris, aes(Species, Sepal.Length)) + geom_boxplot() + 
  theme_classic() + 
  scale_y_continuous(limits = c(3.5,NA), expand = c(0,0), 
                     breaks = c(3.5, 4:7)) + 
  theme(axis.line.y = element_blank()) +
  annotate(geom = "segment", x = -Inf, xend = -Inf, y = -Inf, yend = Inf)

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

Теперь вы можете подумать, где начинаются фактические данные и где хорошее место для разрыва. Вы должны проверить вручную; например min(iris$Sepal.Length) и подумайте, куда пойдут галочки. Это личное суждение.

Я обнаружил, что самое низкое значение было 4,3. Я знал, что хочу, чтобы разрыв был ниже минимума, и я хотел, чтобы разрыв был длиной около 0,5 единицы. Поэтому я решил поставить галочку на 3,5, а затем каждое целое число с breaks = c(3.5, 4:7).


ggplot(iris, aes(Species, Sepal.Length)) + geom_boxplot() + 
  theme_classic() + 
  scale_y_continuous(limits = c(3.5,NA), expand = c(0,0), 
                     breaks = c(3.5, 4:7), labels = c(0, 4:7)) + 
  theme(axis.line.y = element_blank()) +
  annotate(geom = "segment", x = -Inf, xend = -Inf, y = -Inf, yend = Inf)

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

Теперь нам нужно перемаркировать отметку 3,5 так, чтобы она была фальшивым нулем с помощью labels = c(0, 4:7).


ggplot(iris, aes(Species, Sepal.Length)) + geom_boxplot() + 
  theme_classic() + 
  scale_y_continuous(limits = c(3.5,NA), expand = c(0,0), 
                     breaks = c(3.5, 4:7), labels = c(0, 4:7)) + 
  theme(axis.line.y = element_blank()) +
  annotate(geom = "segment", x = -Inf, xend = -Inf, y = -Inf, yend = Inf) +
  annotate(geom = "segment", x = -Inf, xend = -Inf, y =  3.5, yend = 4,
           linetype = "dashed", color = "white")

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

Теперь мы рисуем белую пунктирную линию над нарисованной вручную осевой линией, идущей от нашего фальшивого нуля (y = 3,5) до самой нижней истинной деления (y = 4).

Учтите, что грамматика графики — это зрелая философия; то есть каждый элемент имеет вдумчивое обоснование. Тот факт, что это сложно сделать, имеет веские причины, и вам нужно подумать, имеют ли ваши собственные причины достаточный вес для другой стороны.

person Brian    schedule 25.09.2017
comment
Идеальный! Это сработало очень хорошо! Сюжет выглядит довольно хорошо сейчас! Большое спасибо! - person Z.Kipp; 27.09.2017
comment
@ Z.Kipp Z.Kipp, если вас устраивает этот ответ, вы должны нажать на галочку, чтобы отметить это как ответ. - person Brandon; 25.01.2018