Круговой график в ggplot2 с линейными сегментами, связанными в r
Я пытаюсь создать круговой сюжет и застрял в точке:
dat1 <- data.frame (xvar = 1:10, y = 6, ymin = 4, ymax = 4.5)
Используя эти данные, я могу создать круговой ленточный график в ggplot2
require(ggplot2)
ggplot(dat1, aes(x=xvar, y=y)) + geom_ribbon(aes(ymin=ymin, ymax=ymax),
col = "blue", fill = "blue2") + ylim (c(0,6)) + coord_polar()
![]()
Однако я хочу больше.
Я хочу заполнить сегмент ленты разными цветами и метками, используя следующие данные.
filld <- data.frame (start = c(1, 4, 6, 7.5, 8, 9), end = c(4, 6, 7.5, 8, 9, 10),
label = c("A", "B", "C", "A", "C", "D"))
filld
## start end label
## 1 1.0 4.0 A
## 2 4.0 6.0 B
## 3 6.0 7.5 C
## 4 7.5 8.0 A
## 5 8.0 9.0 C
## 6 9.0 10.0 D
Лента будет заполнена другим цветом по переменной метки. Например, сегмент A начинается с 1 и заканчивается на 4. Затем сегмент B начинается и заканчивается на 6 и заполняется другим цветом. Сегменты с одинаковой меткой (например, A и C) будут соединены линией.
Получившийся сюжет будет выглядеть так: ![]()
Ответы
Ответ 1
Вот пример:
filld$p <- rowMeans(subset(filld, select = c(start, end)))
ggplot(filld, aes(xmin = start, xmax = end, ymin = 4, ymax = 5, fill = label)) +
geom_rect() +
geom_segment(data = subset(filld, label %in% label[duplicated(label)]),
aes(x = p, y = 0, xend = p, yend = 4, colour = label),
size = 2, show_guide = FALSE) +
geom_text(aes(x = p, y = 4.5, label = label), colour = "white", size = 10) +
coord_polar() +
scale_y_continuous(limits = c(0, 5))
![]()
обновленный
Я не рекомендую, но как-то так:
filld <- data.frame (start = c(1, 4, 6, 7.5, 8, 9), end = c(4, 6, 7.5, 8, 9, 10),
label = c("A", "B", "C", "A", "C", "D"))
filld$p <- rowMeans(subset(filld, select = c(start, end)))
filld <- merge(filld, ddply(filld, .(label), summarize, p2 = mean(p)))
lnd <- subset(filld, label %in% label[duplicated(label)])
lnd <- ddply(lnd, .(label), function(x) {
x <- seq(x$p[1], x$p[2], length = 100)
y <- 4.5 + ((x - mean(x))^2 - (x[1]-mean(x))^2) / (x[1]-mean(x))^2 * 3 + sin(x*3*pi) * 0.1
data.frame(x, y)
})
p <- ggplot(filld, aes(xmin = start, xmax = end, ymin = 4, ymax = 5, colour = label, fill = label)) +
geom_line(aes(x, y, xmin = NULL, ymin = NULL, xmax = NULL, ymax = NULL), data = lnd, size = 2) +
geom_rect() +
geom_text(aes(x = p, y = 4.5, label = label), colour = "white", size = 10) +
coord_polar() +
scale_y_continuous(limits = c(0, 5))
p
![]()
Возможно, то, что вы хотите, выходит за рамки ggplot2.
Ответ 2
Посмотрите ggbio. Этот пакет расширяет ggplot2 и грамматику графики до последовательности данных (биоинформатика), но они, похоже, решают вашу проблему (например, см. здесь). Взглянув на исходный код, пакет может направить вас к более универсальному решению.
Ответ 3
Добавьте ymin и т.д., Чтобы заполнить d
fd <- data.frame(filld, ymin = 4, y =6, ymax = 4.5)
Затем используйте geom_rect
с label
столбца в качестве fill
и эстетики colour
ggplot(fd, aes(x=start,xmin = start, xmax = end, y=y)) +
geom_rect(aes(ymin=ymin, ymax=ymax, fill = label )) +
ylim (c(0,6)) +
coord_polar()
![]()
Добавьте строки:
## calculate the midpoint for each segment
fd$xmid <- apply(fd[,1:2],1,mean)
## get the replicate id for the labels (what occurence is this)
library(plyr)
library(reshape2)
fd1 <- ddply(fd, .(label), mutate, id = 1:length(xmid))
## reshape to wide, subsetting only with more than one rep
.lines <- na.omit(dcast(fd1, label~id, value.var = 'xmid'))
## add a mid point between the mid points
.lines$mid <- apply(.lines[,2:3],1,mean)
## reshape to long, and add some y values
ld <- data.frame(arrange(melt(.lines,value.name = 'x'), label, x), y = rep(c(4,3,4),2))
ggplot(fd) +
geom_rect(aes(x=start,xmin = start, xmax = end, y=y,ymin=ymin, ymax=ymax, fill = label )) +
ylim (c(0,6)) +
coord_polar() + geom_path(data = ld, aes(x=x,y=y,colour = label))
![]()
Линии уродливые, но есть!