Минимизировать или удалить пробелы с прерывистой осью или, в идеале, изменить масштаб оси — пытаюсь найти решение — R

#r #ggplot2 #scatter-plot #facet #yaxis

#r #ggplot2 #точечный график #фасет #yaxis

Вопрос:

Я пытался создать график, который имеет нелинейное (и не логарифмическое) масштабирование по оси. В идеале график не должен быть прерывистым. Это трудно объяснить, поэтому я покажу это с картинками. Мой текущий график использует преобразованный масштаб ln, чтобы дать: введите описание изображения здесь

Проблема в том, что большая часть моих данных обычно регистрируется с перекошенным логом, и в идеале я хотел бы, чтобы большая часть данных была сосредоточена на графике. Если бы я мог сделать это идеально, ось масштабировалась бы как:

Верхние 20% графика = 1,001-40,000

Середина 30% графика = 201-1000

Уменьшить 50% графика = 1-200

Чтобы попытаться это сделать, я попробовал пакет: gg.gap . Я думал, что использование прерывистой оси было бы хорошо, но это вводит пробелы. Из того, что я могу сказать, их нельзя минимизировать. Я также попытался разделить три графика по вертикали. Используя cowplots, я добился этого:

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

Это намного ближе к тому, что я хочу, но проблема в том, что пробелы все еще существуют, и то, как работают поля графика, приводит к тому, что некоторые точки данных делятся пополам, оставляя странные полукруги на концах. — Примечание: я исправил это с помощью » coord_cartesian (clip = «off»)», точки больше не обрезаются.

Чтобы решить эту проблему, я в растерянности и подумал, что обращусь за помощью. Вот минимальный воспроизводимый код (все еще длинный, но он показывает все, что создает каждый график).

 #Generate Random Data set:
set.seed(1)
graphdata <-as.data.frame(rlnorm(29000, meanlog = 4.442651, sdlog = 0.85982))
colnames(graphdata)[1] <- "values"
high_values <- as.data.frame(rlnorm(1000, meanlog = 9.9, sdlog = 0.85))
colnames(high_values)[1] <- "values"
graphdata <- rbind(graphdata,high_values)
graphdata$values <- round(graphdata$values, digits = 0)

#Current Plot
#I used 'Trans = 'log'' to set the axis to a natural log scale. It has worked until my data have become large enough that I need to change the scaling of the axis for better visibility.
library(tidyverse)
graph <- ggplot(graphdata, aes(y = values, x=1)) 
  geom_jitter(aes(colour = cut(values, c(0,100,200,Inf))), alpha = 0.2, size = 0.5) 
  scale_color_manual(values = c("#F0CF19","#F07C0B", "#D52828")) 
  scale_y_continuous(breaks = c(0,20,50,100,200,500,1000,2000,5000,10000,20000,40000), trans='log', limits = c(14, 40001), expand = c(0, 0)) 
  labs(y = "Values", x = NULL) 
  scale_x_continuous(expand = c(0.01, 0))  coord_cartesian(clip = "off") 
   theme_classic() 
  theme(legend.position = "none",
        axis.text.x = element_blank(),
        axis.ticks.x = element_blank(),
        axis.line.x = element_blank())
graph

#My attempt to get an altered axis arrangement - using multiple plots and stacking them:

graph1 <- ggplot(graphdata, aes(y = values, x=1)) 
  geom_jitter(aes(colour = cut(values, c(0,100,200,Inf))), alpha = 0.2, size = 0.5) 
  scale_color_manual(values = c("#F0CF19","#F07C0B", "#D52828")) 
  scale_y_continuous(breaks = c(0,20,50,100,200), trans='log', limits = c(14, 200), expand = c(0, 0)) 
  labs(y = NULL, x = NULL) 
  scale_x_continuous(expand = c(0.01, 0)) 
   theme_classic()  coord_cartesian(clip = "off") 
  theme(legend.position = "none",
        axis.text.x = element_blank(),
        axis.ticks.x = element_blank(),
        axis.line.x = element_blank(),
        plot.margin = margin(t=0, unit = "pt"))
graph1

graph2 <- ggplot(graphdata, aes(y = values, x=1)) 
  geom_jitter(aes(colour = cut(values, c(0,100,200,Inf))), alpha = 0.2, size = 0.5) 
  scale_color_manual(values = c("#F0CF19","#F07C0B", "#D52828")) 
  scale_y_continuous(breaks = c(500,1000), trans='log', limits = c(201, 1000), expand = c(0, 0)) 
  labs(y = "Values", x = NULL) 
  scale_x_continuous(expand = c(0.01, 0)) 
   theme_classic()  coord_cartesian(clip = "off") 
  theme(legend.position = "none",
        axis.text.x = element_blank(),
        axis.ticks.x = element_blank(),
        axis.line.x = element_blank(),
        plot.margin = margin(t=0, unit = "pt"))
graph2

graph3 <- ggplot(graphdata, aes(y = values, x=1)) 
  geom_jitter(aes(colour = cut(values, c(0,100,200,Inf))), alpha = 0.2, size = 0.5) 
  scale_color_manual(values = c("#F0CF19","#F07C0B", "#D52828")) 
  scale_y_continuous(breaks = c(10000,20000,40000), trans='log', limits = c(1001, 40001), expand = c(0, 0)) 
  labs(y = NULL,x = NULL) 
  scale_x_continuous(expand = c(0.01, 0)) 
   theme_classic()  coord_cartesian(clip = "off") 
  theme(legend.position = "none",
        axis.text.x = element_blank(),
        axis.ticks.x = element_blank(),
        axis.line.x = element_blank(),
        plot.margin = margin(t=0, unit = "pt"))
graph3

#Using Cowplot, I stichted together three panels to make one graph that is close to what I want. But the problem lies with the white space between the panels. I want to get rid of it. Also, this method leads to some points being cut-off, leaving wierd half circles. 
library(cowplot);library(grid); library(egg)
graph4 <- cowplot::plot_grid(graph3, graph2, graph1, align = "v", ncol = 1, rel_heights = c(0.25,0.25,0.5))
graph4 <- set_panel_size(graph4, width = unit(7, "cm"), height = unit(6, "cm"))
 grid.newpage()
 grid.draw(graph4)
 

Спасибо!

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

Комментарии:

1. Я добавил «coord_cartesian (clip = «off»)», чтобы предотвратить отсечение. Этот аспект был исправлен.

Ответ №1:

Похоже, мне нужно было добавить слой «нулевых» графиков, чтобы отрегулировать интервал между пробелами. Я убедился, что поля моего графика равны 0 для верхнего и нижнего, а затем добавил НУЛЕВОЙ график и отрегулировал интервал как отрицательный. Вот скорректированный код:

 #Generate Random Data set:
set.seed(1)
graphdata <-as.data.frame(rlnorm(29000, meanlog = 4.442651, sdlog = 0.85982))
colnames(graphdata)[1] <- "values"
high_values <- as.data.frame(rlnorm(1000, meanlog = 9.9, sdlog = 0.85))
colnames(high_values)[1] <- "values"
graphdata <- rbind(graphdata,high_values)
graphdata$values <- round(graphdata$values, digits = 0)

graph1 <- ggplot(graphdata, aes(y = values, x=1)) 
  geom_jitter(aes(colour = cut(values, c(0,100,200,Inf))), alpha = 0.2, size = 0.5) 
  scale_color_manual(values = c("#F0CF19","#F07C0B", "#D52828")) 
  scale_y_continuous(breaks = c(0,20,50,100,200), trans='log', limits = c(14, 200), expand = c(0, 0)) 
  labs(y = NULL, x = NULL) 
  scale_x_continuous(expand = c(0.01, 0)) 
   theme_classic() 
   coord_cartesian(clip = "off") 
  theme(legend.position = "none",
        axis.text.x = element_blank(),
        axis.ticks.x = element_blank(),
        axis.line.x = element_blank(),
        axis.title.x = element_blank(),
        axis.title.y = element_blank(),
        plot.margin = margin(0,0,0,0))
graph1

graph2 <- ggplot(graphdata, aes(y = values, x=1)) 
  geom_jitter(aes(colour = cut(values, c(0,100,200,Inf))), alpha = 0.2, size = 0.5) 
  scale_color_manual(values = c("#F0CF19","#F07C0B", "#D52828")) 
  scale_y_continuous(breaks = c(500,1000), trans='log', limits = c(201, 1000), expand = c(0, 0)) 
  labs(y = "Longer title Values", x = NULL) 
  scale_x_continuous(expand = c(0.01, 0)) 
   theme_classic() 
   coord_cartesian(clip = "off") 
  theme(legend.position = "none",
        axis.text.x = element_blank(),
        axis.ticks.x = element_blank(),
        axis.line.x = element_blank(),
        axis.title.x = element_blank(),
        plot.margin = margin(0,0,0,0))
graph2

graph3 <- ggplot(graphdata, aes(y = values, x=1)) 
  geom_jitter(aes(colour = cut(values, c(0,100,200,Inf))), alpha = 0.2, size = 0.5) 
  scale_color_manual(values = c("#F0CF19","#F07C0B", "#D52828")) 
  scale_y_continuous(breaks = c(10000,20000,40000), trans='log', limits = c(1001, 40001), expand = c(0, 0)) 
  labs(y = NULL,x = NULL) 
  scale_x_continuous(expand = c(0.01, 0)) 
   theme_classic() 
   coord_cartesian(clip = "off") 
  theme(legend.position = "none",
        axis.text.x = element_blank(),
        axis.ticks.x = element_blank(),
        axis.line.x = element_blank(),
        axis.title.x = element_blank(),
        axis.title.y = element_blank(),
        plot.margin = margin(0,0,0,0))
graph3

#Using Cowplot, I stichted together three panels to make one graph that is close to what I want. But the problem lies with the white space between the panels. I want to get rid of it. Also, this method leads to some points being cut-off, leaving wierd half circles. 
library(cowplot);library(grid)
graph4 <- cowplot::plot_grid(graph3,NULL, graph2, NULL,graph1, align = "v", ncol = 1, rel_heights = c(0.25,-0.01,0.25,-0.01,0.5)) #adjust spacing with the negative values here.
graph4 <- set_panel_size(graph4, width = unit(7, "cm"), height = unit(6, "cm"))
 grid.newpage()
 grid.draw(graph4)
 

В итоге я получаю этот график:
введите описание изображения здесь

В целом я рад, что теперь могу отрегулировать интервал. Однако это приводит к другой проблеме с названием оси. Похоже, что наложение слоев делает последний приведенный график самым верхним графиком. Заголовок среднего графика отсекается от нижнего графика. Вот что я имею в виду (заголовок должен читать «более длинные значения заголовка»): введите описание изображения здесь

Итак, это следующее препятствие, но может быть еще один вопрос, который я должен задать в отдельном сообщении.