Как сделать так, чтобы мои точки совпадали с моим боксплотом на графике basi c r? - PullRequest
0 голосов
/ 14 апреля 2020

Я строю диаграмму и линию, показывающую две разные переменные с общей осью X, но я не могу выровнять их по одной точке на оси X. Таким образом, точки линии смещены от центра бокса. Есть ли способ это исправить? Это мой код и график, как я его получил. enter image description here

    ##Plotting variation total VOC vs temperatura per month
par(mar=c(2, 5, 1, 4))
boxplot(data=general_voc, daily_voc~Month, 
        xlab='', ylab='',
        col=color_pal[1],
        bg=color_pal[1],
        type = 'l',
        main='',cex=0.1,yaxt='n',
        ann = FALSE)
axis(2, ylim=c(0,max(general_voc$daily_voc,na.rm = T)),
     col='black',lwd=0.2,cex = 0.8,las=1)
mtext(2,text='Total BVOC (ppb)',line=2.5,
      col="black",cex = 1.2,las=0)
par(new=T) #START A NEW PLOT OVER THE DAME FRAME
plot.default(mean_temp$Month,mean_temp$temp,#plot temperature
     xlab='', ylab='',
     col=color_pal[2],
     bg=color_pal[2],
     type = 'b',
     main='',cex=0.8,yaxt='n',
     xaxt='n')
axis(4, ylim=c(0,max(mean_temp$temp,na.rm = T)),#Second axis set up
     col=color_pal[2],
     col.axis = color_pal[2],
     lwd=0.2,
     cex = 0.8,
     las=1)
mtext(4,text='avg T (°C)',line=2.5,#Add the label second y axis
      col = color_pal[2],
      cex = 1.2,las=0)

Редактировать: Добавление нового графика с наблюдаемым смещением между графиками и выборкой данных. avg_temp:

  month  temp
  <dbl> <dbl>
1     2  22.4
2     3  20.6
3     4  18.3
4     5  15.0
5     6  11.8

general_vo c:

    day month daily_voc avg_temp avg_voc Month
  <dbl> <dbl>     <dbl>    <dbl>   <dbl> <chr>
1     1     3    19.2       23.2  1.20   Mar  
2     1     5    11.9       17.9  0.853  May  
3     1     6     0.247     13.8  0.0145 Jun  
4     2     3    15.7       23.2  1.30   Mar  
5     2     4     0         19.8  0      Apr  
6     2     5    13.6       19.7  0.905  May 

Ответы [ 2 ]

0 голосов
/ 14 апреля 2020

Бокплоты предполагают, что групповая переменная является фактором, поэтому отметки по оси x равны seq (1, n), где n - количество уровней фактора. Ваши данные general_vo c имеют только 4 уровня для Месяца, и они расположены на позициях 1, 2, 3 и 4 оси X. Ваш второй график использует месяц на оси X, переменную Numberri c, и уникальными значениями являются 2, 3, 4, 5 и 6. Начало нового графика с параметром par (new = TRUE) будет игнорировать значения предыдущих осей.

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

library(dplyr)

data <- full_join(general_voc, mean_temp, by="month")

par(mar=c(2, 5, 1, 4))
boxplot(data=data, daily_voc~month, na.action="na.pass",
        xlab='', ylab='', 
        ylim=c(0,25),
        type = 'l',
        main='',cex=0.1,yaxt='n',
        ann = FALSE, xaxt='n')
axis(side=1, at=1:5, labels=month.abb[sort(unique(data$month))])
axis(2, ylim=c(0,max(general_voc$daily_voc,na.rm = T)),
     col='black',lwd=0.2,cex = 0.8,las=1)
mtext(2,text='Total BVOC (ppb)', line=2.5,
      col="black",cex = 1.2,las=0)

points(data=data, temp~factor(month), 
             xlab='', ylab='', 
             type = 'p',
             main='',cex=0.8, yaxt='n',
             xaxt='n')

enter image description here


Данные :

general_voc <- structure(list(day = c(1L, 1L, 1L, 2L, 2L, 2L), month = c(3L, 
5L, 6L, 3L, 4L, 5L), daily_voc = c(19.2, 11.9, 0.247, 15.7, 0, 
13.6), avg_temp = c(23.2, 17.9, 13.8, 23.2, 19.8, 19.7), avg_voc = c(1.2, 
0.853, 0.0145, 1.3, 0, 0.905), Month = structure(c(3L, 4L, 2L, 
3L, 1L, 4L), .Label = c("Apr", "Jun", "Mar", "May"), class = "factor")), class = "data.frame", row.names = c("1", 
"2", "3", "4", "5", "6"))

mean_temp <- structure(list(month = 2:6, temp = c(22.4, 20.6, 18.3, 15, 11.8
)), class = "data.frame", row.names = c("1", "2", "3", "4", "5"
))
0 голосов
/ 14 апреля 2020

Вместо использования plot.default, вы можете использовать points, чтобы выровнять точки по оси x вашего боксплота.

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

general_voc <- data.frame(Month = sample(c("Feb","Mar","May","Jun"),100,replace = TRUE),
                         daily_voc = sample(0:100,100,replace = TRUE))
general_voc$Month <- factor(general_voc$Month, levels = c("Feb","Mar","May","Jun"))

mean_temp <- data.frame(Month = c("Feb","Mar","May","Jun"),
                        temp = c(22,20,15,11))
mean_temp$Month <- factor(mean_temp$Month, levels = c("Feb","Mar","May","Jun"))

Чтобы построить два фрейма данных с различным диапазоном значений, вам необходимо увеличить значения для ваших точек, чтобы они совпадали. диапазон значений, используемых для boxplot:

mean_temp$temp2 <- mean_temp$temp * max(general_voc$daily_voc)/max(mean_temp$temp)

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

par(mar=c(2, 5, 1, 4))
boxplot(data=general_voc, daily_voc~Month, 
        xlab='', ylab='',
        col="green",
        #bg=color_pal[1],
        type = 'l',
        main='',cex=0.1,yaxt='n',
        ann = FALSE)
axis(2, ylim=c(0,max(general_voc$daily_voc,na.rm = T)),
     col='black',lwd=0.2,cex = 0.8,las=1)
mtext(2,text='Total BVOC (ppb)',line=2.5,
      col="black",cex = 1.2,las=0)

points(x = mean_temp$Month, y = mean_temp$temp2, col = "blue", type = "b")
axis(4, ylim=c(0,max(mean_temp$temp2,na.rm = T)),#Second axis set up
     col="blue",
     col.axis = "blue",
     lwd=0.2,
     cex = 0.8,
     las=1, 
     at = seq(0,max(mean_temp$temp2),length.out = 5),
     labels = seq(0,max(mean_temp$temp),length.out = 5))
mtext(4,text='avg T (°C)',line=2.5,#Add the label second y axis
      col = "blue",
      cex = 1.2,las=0)

enter image description here

Отвечает ли он на ваш вопрос?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...