Наложение двух аллювиальных участков с одинаковыми размерами - PullRequest
2 голосов
/ 26 февраля 2020

Я пытаюсь нанести прямоугольник поверх аллювиального графика в R. Мои коды:

library(alluvial)
tit <- as.data.frame(Titanic)
tit2d <- aggregate(Freq ~ Class + Survived, data=tit, sum)


alluvial(tit2d, freq = tit2d$Freq, xw = 0.0, alpha = 0.8,
         gap.width = 0.1, col = "steelblue", border = "white",
         layer = tit2d$Survived != "Yes", blocks = F)

par(new = TRUE) 
plot(c(0, 1), c(0, 1), type = "n", xlab = "", ylab = "")
rect(0, 0, 0.3, 0.4, col = "red")

Но как мне убедиться, что координаты обоих графиков совпадают, как мой прямоугольник основан на аллювиальных координатах?

Ответы [ 2 ]

1 голос
/ 27 февраля 2020

Можно подумать Почему эта функция возвращает только матрицы y-координат конечных точек?
Из документа alluvial написано:

x -координаты - это последовательные натуральные числа .

Пояснение

В вашем примере на графике три колонны, а это означает их средние точки расположены в 1, 2, 3 соответственно. Однако где находятся левая и правая границы каждой колонны? Я думаю, что вы проигнорировали важный аргумент cw из alluvial(), который контролирует ширину столбов. Если вы не установите его, он примет значение по умолчанию 0.1. Левая и правая границы каждой колонны будут

Теперь вы можете легко найти обе границы колонны Eanch.

temp <- alluvial(tit2d, freq = tit2d$Freq, xw = 0, alpha = 0.8,
                 gap.width = 0.1, col = "steelblue", border = "white",
                 layer = tit2d$Survived != "Yes", blocks = F)

par(xpd = TRUE)
abline(v = 1:3, lwd = 3, col = "red")
abline(v = 1:3 - 0.1, lwd = 3, col = "blue")
abline(v = 1:3 + 0.1, lwd = 3, col = "green")

Если вы хотите выделить определенный прямоугольник:

par(xpd = TRUE)
y <- temp$endpoints

# bottom-left rectangle
rect(1 - 0.1, y[[1]][1, 1],
     1 + 0.1, y[[1]][1, 2], col = "red")

# the second pillar, the fourth rectangle from the bottom
rect(2 - 0.1, y[[2]][4, 1],
     2 + 0.1, y[[2]][4, 2], col = "orange")


Почему par(xpd = TRUE)?

par("xpd") можно установить

  • FALSE (по умолчанию): все графики обрезается до области «сюжета»
  • TRUE: все черчение обрезается до области «рисунка»
  • NA: все черчение обрезается до области «устройства»

Если вы не измените значение по умолчанию, все низкоуровневые функции построения графиков, например, points(), abline(), rect(), text() ..., будут обрезаны при выходе "сюжетной" области. Вы можете использовать box(), чтобы увидеть, где находится область «сюжета».


Заключение

  1. Аргумент cw = 0.1 ( дефолт). Вы можете изменить его, но x-координаты будут другими.

  2. Set par(xpd = TRUE).


Дополнение

Если вы хотите изменить порядок рисования полос, попробуйте настроить аргумент layer. Это может быть логический или числовой c вектор. Чем больше число, тем раньше нарисована полоса, то есть она будет ниже полосы меньших чисел.

В вашем примере вы можете изменить порядок в соответствии с рангом Freq.
Обратите внимание на разницу в следующем:

  • rank(tit2d$Freq) отображать меньшие значения в нижние ранги.
  • rank(-tit2d$Freq) отображать меньшие значения в верхние ранги.
tit2d$Freq
# [1] 122 167 528 673 203 118 178 212

rank(tit2d$Freq)
# [1] 2 3 7 8 5 1 4 6

rank(-tit2d$Freq)
# [1] 7 6 2 1 4 8 5 3

Поэтому в комментарии требуется последнее.

alluvial(tit2d, freq = tit2d$Freq, xw = 0, alpha = 0.8,
         gap.width = 0.1, col = "steelblue", border = "white",
         layer = rank(-tit2d$Freq), blocks = F)

1 голос
/ 26 февраля 2020

Обычно команда par ("usr") может сообщить вам крайние значения текущей области печати. Но здесь это немного сложно, потому что аллювиальная функция регулирует графический параметр mar внутри функции. Это меняет поля на c(2,1,1,1). В конце функции он возвращает поля обратно к тому, что было изначально. Поля по умолчанию: c (5, 4, 4, 2) + 0,1, представляющие количество линий (1 строка = 1/5 дюйма) между нижним, левым, верхним и правым внешними полями для области построения. Посмотрите на страницу справки для par и прокрутите вниз, пока не дойдете до Май, чтобы увидеть хорошую диаграмму. Еще одна настройка, сделанная аллювиальной функцией, заключается в изменении значения по умолчанию style осей с обычных (xaxs = "r", yaxs = "r") на внутренние (xaxs = "i", yaxs = "i" "), что заставляет оси расширяться немного дальше.

Например:

alluvial( tit2d, freq=tit2d$Freq, xw=0.0, alpha=0.8,
                gap.width=0.1, col= "steelblue", border="white",
                layer = tit2d$Survived != "Yes", blocks = F )

u <- par("usr"); u
par(new=TRUE) 
plot(0, type= "n", xlab = "", ylab = "", las=1, xaxs = "i", yaxs = "i", 
xlim=c(u[1], u[2]), ylim=c(u[3], u[4]))
rect(u[1], u[3], u[2], u[4], col = "red")

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

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

op <- par(mar=c(2,1,1,1))
par(new=TRUE) 
plot(0, type= "n", xlab = "", ylab = "", las=1, 
     xlim=c(u[1], u[2]), ylim=c(u[3], u[4]))
rect(u[1], u[3], u[2], u[4], col = "green")
par(op)

Ваш зеленый прямоугольник теперь должен покрывать весь аллювиальный график.

Редактировать : выделить нижние прямоугольники:

par(new=TRUE, mar=c(2,1,1,1)) 
u <- par("usr")
rect(u[1], temp$endpoints[[1]][1,1], u[1]+0.2, # Note: cw has a default value of 0.1
   temp$endpoints[[1]][1,2], col = "red")

rect(u[1]+1, temp$endpoints[[1]][1,1], u[1]+1.2, 
   temp$endpoints[[1]][1,2], col = "red")

rect(u[1]+2, temp$endpoints[[1]][1,1], u[1]+2.2, 
   temp$endpoints[[1]][1,2], col = "red") 

Редактировать : Спасибо @Darren Tsai за указание на то, что низкоуровневые функции построения графиков, такие как rect(), не имеют аргумента "xaxs" для изменения стиля оси, поскольку оси уже есть!

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