ggplot2 dường như không có cách tích hợp để xử lý overplotting cho văn bản trên scatter plots. Tuy nhiên, tôi có một tình huống khác nhau, nơi các nhãn là những người trên một trục rời rạc và tôi tự hỏi nếu ai đó ở đây có một giải pháp tốt hơn so với những gì tôi đã làm.Cách đối phó với nhãn ggplot2 và chồng lên nhau trên trục rời
Một số mã ví dụ:
library(ggplot2)
#some example data
test.data = data.frame(text = c("A full commitment's what I'm thinking of",
"History quickly crashing through your veins",
"And I take A deep breath and I get real high",
"And again, the Internet is not something that you just dump something on. It's not a big truck."),
mean = c(3.5, 3, 5, 4),
CI.lower = c(4, 3.5, 5.5, 4.5),
CI.upper = c(3, 2.5, 4.5, 3.5))
#plot
ggplot(test.data, aes_string(x = "text", y = "mean")) +
geom_point(stat="identity") +
geom_errorbar(aes(ymax = CI.upper, ymin = CI.lower), width = .1) +
scale_x_discrete(labels = test.data$text, name = "")
Vì vậy, chúng ta thấy rằng các nhãn trục x là trên đầu trang của mỗi khác. Hai giải pháp cần lưu ý: 1) viết tắt nhãn và 2) thêm dòng mới vào nhãn. Trong nhiều trường hợp (1) sẽ làm, nhưng trong một số trường hợp nó không thể được thực hiện. Vì vậy, tôi đã viết một chức năng cho dòng mới thêm (\n
) mỗi ký tự n'th để các dây để tránh tên chồng chéo:
library(ggplot2)
#Inserts newlines into strings every N interval
new_lines_adder = function(test.string, interval){
#length of str
string.length = nchar(test.string)
#split by N char intervals
split.starts = seq(1,string.length,interval)
split.ends = c(split.starts[-1]-1,nchar(test.string))
#split it
test.string = substring(test.string, split.starts, split.ends)
#put it back together with newlines
test.string = paste0(test.string,collapse = "\n")
return(test.string)
}
#a user-level wrapper that also works on character vectors, data.frames, matrices and factors
add_newlines = function(x, interval) {
if (class(x) == "data.frame" | class(x) == "matrix" | class(x) == "factor") {
x = as.vector(x)
}
if (length(x) == 1) {
return(new_lines_adder(x, interval))
} else {
t = sapply(x, FUN = new_lines_adder, interval = interval) #apply splitter to each
names(t) = NULL #remove names
return(t)
}
}
#plot again
ggplot(test.data, aes_string(x = "text", y = "mean")) +
geom_point(stat="identity") +
geom_errorbar(aes(ymax = CI.upper, ymin = CI.lower), width = .1) +
scale_x_discrete(labels = add_newlines(test.data$text, 20), name = "")
Và kết quả là:
Sau đó, người ta có thể dành chút thời gian chơi với kích thước khoảng thời gian để tránh có quá nhiều khoảng trống giữa các nhãn.
Nếu số lượng nhãn khác nhau, loại giải pháp này không tốt, vì kích thước khoảng thời gian tối ưu thay đổi. Ngoài ra, bởi vì phông chữ bình thường không phải là một khoảng trắng, văn bản của các nhãn cũng có tác dụng trên chiều rộng, và do đó người ta phải cẩn thận hơn trong việc chọn khoảng thời gian tốt (có thể tránh điều này bằng cách sử dụng phông chữ không gian đơn) , nhưng chúng rộng hơn). Cuối cùng, hàm new_lines_adder()
là ngu xuẩn ở chỗ nó sẽ tách các từ thành hai cách ngớ ngẩn mà con người sẽ không làm. Ví dụ. ở trên nó chia "hơi thở" thành "br \ vòng hoa". Người ta có thể viết lại nó để tránh vấn đề này.
Bạn cũng có thể giảm kích thước phông chữ, nhưng đây là giao dịch với khả năng đọc và thường giảm kích thước phông chữ là không cần thiết.
Cách tốt nhất để xử lý loại chèn nhãn này là gì?
Tôi thường đối phó với các nhãn trùng lặp bằng cách xoay chúng: '+ chủ đề (axis.text.x = element_text (angle = 60, hjust = 1))' (nhưng nó không lý tưởng nếu chúng rất dài, vì nó tạo ra margin lớn) – scoa