2016-03-11 45 views
5

Tôi có một biểu đồ thanh xếp chồng lên nhau trông như thế này:Tạo một thang màu khác nhau cho mỗi thanh trong một ggplot2 xếp chồng lên nhau biểu đồ hình cột

Number of patients on each drug by drug class

Trong khi các màu sắc nhìn đẹp, nó là khó hiểu có rất nhiều các màu tương tự đại diện cho các loại thuốc khác nhau. Tôi muốn có một bảng màu riêng biệt cho mỗi thanh trong đồ thị, ví dụ, class1 có thể sử dụng bảng "Blues" trong khi class2 có thể sử dụng bảng "BuGn" (tên bảng màu được tìm thấy here)

Tôi có đã tìm thấy một số trường hợp trong đó mọi người đã mã hóa màu sắc theo cách thủ công cho mỗi thanh (chẳng hạn như here), nhưng tôi không chắc chắn liệu tôi có thể yêu cầu không - những thanh này sẽ cần phải dựa trên bảng màu, vì có quá nhiều loại thuốc trong mỗi loại thuốc.

Mã để tạo ra các đồ thị trên:

library(ggplot2) 
library(plyr) 
library(RColorBrewer) 

drug_name <- c("a", "a", "b", "b", "b", "c", "d", "e", "e", "e", "e", "e", "e", 
      "f", "f", "g", "g", "g", "g", "h", "i", "j", "j", "j", "k", "k", 
      "k", "k", "k", "k", "l", "l", "m", "m", "m", "n", "o") 
df <- data.frame(drug_name) 

#get the frequency of each drug name 
df_count <- count(df, 'drug_name') 

#add a column that specifies the drug class 
df_count$drug_class <- vector(mode='character', length=nrow(df_count)) 

df_count$drug_class[df_count$drug_name %in% c("a", "c", "e", "f")] <- 'class1' 

df_count$drug_class[df_count$drug_name %in% c("b", "o")] <- 'class2' 

df_count$drug_class[df_count$drug_name %in% c("d", "h", "i")] <- 'class3' 

df_count$drug_class[df_count$drug_name %in% c("g", "j", "k", "l", "m", "n")] <- 'class4' 

#expand color palette (from http://novyden.blogspot.com/2013/09/how-to-expand-color-palette-with-ggplot.html) 

colorCount = length(unique(df_count$drug_name)) 
getPalette = colorRampPalette(brewer.pal(9, "Set1")) 

test_plot <- ggplot(data = df_count, aes(x=drug_class, y=freq, fill=drug_name)) + geom_bar(stat="identity") + scale_fill_manual(values=getPalette(colorCount)) 

test_plot 
+0

Bạn có thể kiểm tra [** Nhiều thang màu trong một âm mưu thanh xếp chồng lên nhau sử dụng ggplot **] (http://stackoverflow.com/questions/19568901/multiple-colour-scales- in-one-stacked-bar-plot-using-ggplot). Thoạt nhìn nó có vẻ giống như một trường hợp tương tự. – Henrik

Trả lời

2

Các bảng màu khác nhau trên không liên tục chuyển sang các lớp khác nhau - thay vào đó họ âm mưu theo vector tên (a, b, c ...) và do đó được chia thành nhiều lớp khác nhau. Xem ??scale_fill_manual để biết chi tiết.

Để "đối sánh" chúng với từng bộ thanh, chúng tôi cần đặt thứ tự data.frame theo lớp và căn chỉnh các bảng màu phù hợp với tên.

Tạo bảng màu lặp lại để kiểm tra thứ tự chính xác (được mong đợi).

repeating.pal = mapply(function(x,y) brewer.pal(x,y), ncol,  c("Set2","Set2","Set2","Set2")) 

repeating.pal[[2]] = repeating.pal[[2]][1:2] # We only need 2 colors but brewer.pal creates 3 minimum 

repeating.pal = unname(unlist(repeating.pal)) 

Sắp xếp dữ liệu theo lớp (thứ tự chúng tôi muốn các màu sắc ở lại!)

df_count_sorted <- df_count[order(df_count$drug_class),] 

Sao chép thứ tự ban đầu của tên thuốc.

df_count_sorted$labOrder <- df_count$drug_name 

Thêm vào bảng màu thử nghiệm.

df_count$colours<-repeating.pal 

Alter thói quen âm mưu, với fill = labOrder.

ggplot(data = df_sorted, aes(x=drug_class, y=freq, fill=labOrder)) + 
geom_bar(stat="identity", colour="black", lwd=0.2) + 
geom_text(aes(label=paste0(drug_name,": ", freq), y=cum.freq),  colour="grey20") + 
scale_fill_manual(values=df_sorted$colours) + 
guides(fill=FALSE) 

Palette follows expected order

+0

điều này thật tuyệt. Tôi đã tìm ra một cách giải quyết (loại) đã đạt được điều này theo một cách nhưng không giải quyết được hoàn toàn vấn đề. Tôi đã xây dựng trên câu trả lời từ @ eipi10 bằng cách thay thế 'pal <- colorRampPalette (brewer.pal (9," Greens ")) (41)' cho 'pal' đã được định nghĩa trước đó. –

6

Với rất nhiều màu sắc, âm mưu của bạn sẽ gây nhầm lẫn. Nó có thể tốt hơn để chỉ nhãn mỗi phần thanh với tên thuốc và số lượng. Mã dưới đây cho thấy một cách để tạo các bảng màu riêng biệt cho mỗi thanh và cách gắn nhãn các thanh.

Đầu tiên, thêm một cột mà chúng ta sẽ sử dụng cho định vị nhãn thanh:

library(dplyr) # for the chaining (%>%) operator 

## Add a column for positioning drug labels on graph 
df_count = df_count %>% group_by(drug_class) %>% 
    mutate(cum.freq = cumsum(freq) - 0.5*freq) 

Thứ hai, tạo ra bảng màu. Đoạn mã dưới đây sử dụng bốn bảng màu Colorbrewer khác nhau, nhưng bạn có thể sử dụng bất kỳ sự kết hợp nào của các hàm tạo hoặc các phương thức tạo bảng màu để kiểm soát màu sắc như mong muốn.

## Create separate palette for each drug class 

# Count the number of colors we'll need for each bar 
ncol = table(df_count$drug_class) 

# Make the palettes 
pal = mapply(function(x,y) brewer.pal(x,y), ncol, c("BrBG","OrRd","YlGn","Set2")) 
pal[[2]] = pal[[2]][1:2] # We only need 2 colors but brewer.pal creates 3 minimum 
pal = unname(unlist(pal)) # Combine palettes into single vector of colors 

ggplot(data = df_count, aes(x=drug_class, y=freq, fill=drug_name)) + 
    geom_bar(stat="identity", colour="black", lwd=0.2) + 
    geom_text(aes(label=paste0(drug_name,": ", freq), y=cum.freq), colour="grey20") + 
    scale_fill_manual(values=pal) + 
    guides(fill=FALSE) 

enter image description here

Có rất nhiều chiến lược và chức năng để tạo bảng màu. Dưới đây là một phương pháp khác, bằng cách sử dụng chức năng hcl:

lum = seq(100, 50, length.out=4) # Vary the luminance for each bar 
shift = seq(20, 60, length.out=4) # Shift the hues for each bar 

pal2 = mapply(function(n, l, s) hcl(seq(0 + s, 360 + s, length.out=n+1)[1:n], 100, l), 
       ncol, lum, shift) 
pal2 = unname(unlist(pal2)) 
Các vấn đề liên quan