#r #ggplot2
Вопрос:
У меня есть несколько матриц путаницы, и я хочу их сравнить. Я подумал, что было бы здорово визуализировать самое высокое и самое низкое значение для каждой категории на одном графике. Я представляю себе что-то вроде этого (простите меня за уродливые каракули):
Для каждой категории есть верхний прямоугольник, показывающий наибольшее значение во всех матрицах путаницы, нижний прямоугольник показывает наименьшее значение во всех матрицах путаницы. Цвет указывает, к какому набору данных относится прямоугольник.
Итак, как я могу этого достичь? Я подумал , что мог бы использовать его для работы geom_polygon()
, но я никогда им не пользовался и представляю, что это довольно сложная работа. Есть ли способ, который позволил бы мне использовать geom_tile()
, но использовать треугольники вместо прямоугольников? Я видел несколько ggplots с прямоугольниками, которые были горизонтально разделены на меньшие прямоугольники, поэтому я подумал, может быть, есть возможность сделать треугольники тоже?
Вот некоторые фиктивные данные:
datasets <- c("Data Set 1", "Data Set 2", "Data Set 3", "Data Set 4")
df <- data.frame(
"Truth" = c(rep(c("A","B","C","D"), 8)),
"Prediction" = c(rep(c("A","B","C","D"), each = 8)),
"Type" = c(rep(rep(c("min", "max"), each = 4), 4)),
"Data_Set" = sample(datasets, 8*4, replace = TRUE),
"Value" = round(runif(8*4)*100))
Создать один график на максимальное / минимальное значение было бы несложно. Например:
ggplot(df[df$Type == "min",])
geom_tile(aes(x = Truth, y = Prediction, fill = Data_Set))
geom_text(aes(x = Truth, y = Prediction, label = Value))
Но я ищу красивый способ объединить схему листов для максимального и минимального. Я также открыт для других идей. Я предполагаю, что многие люди хотели сравнить несколько матриц путаницы в одном сюжете до меня?
Ответ №1:
Я не могу придумать способ построения треугольников ggplot2
без определения их как многоугольников, что требует небольшого изменения формы данных. Если мы начнем с ваших исходных данных:
datasets <- c("Data Set 1", "Data Set 2", "Data Set 3", "Data Set 4")
set.seed(2)
df <- data.frame(
"Truth" = c(rep(c("A","B","C","D"), 8)),
"Prediction" = c(rep(c("A","B","C","D"), each = 8)),
"Type" = c(rep(rep(c("min", "max"), each = 4), 4)),
"Data_Set" = sample(datasets, 8*4, replace = TRUE),
"Value" = round(runif(8*4)*100))
Теперь получите координаты центра каждой плитки, преобразовав коэффициенты в числа, и добавьте столбец, в котором записан исходный номер строки:
df$x <- as.numeric(factor(df$Truth))
df$y <- as.numeric(factor(df$Prediction))
df$observation <- seq(nrow(df))
Теперь сделайте три копии каждой строки:
df <- df[rep(seq(nrow(df)), each = 3),]
И мы можем вычислить координаты вершин треугольников:
polyxmin <- df$x c(-0.5, 0.5, 0.5)
polyxmax <- df$x c(-0.5, -0.5, 0.5)
polyymin <- df$y c(-0.5, -0.5, 0.5)
polyymax <- df$y c(-0.5, 0.5, 0.5)
df$polyx <- numeric(nrow(df))
df$polyx[df$Type == "min"] <- polyxmin[df$Type == "min"]
df$polyx[df$Type == "max"] <- polyxmax[df$Type == "max"]
df$polyy <- numeric(nrow(df))
df$polyy[df$Type == "min"] <- polyymin[df$Type == "min"]
df$polyy[df$Type == "max"] <- polyymax[df$Type == "max"]
И добавьте места для текста:
df$x[df$Type == "min"] <- df$x[df$Type == "min"] 0.25
df$x[df$Type == "max"] <- df$x[df$Type == "max"] - 0.25
df$y[df$Type == "min"] <- df$y[df$Type == "min"] - 0.25
df$y[df$Type == "max"] <- df$y[df$Type == "max"] 0.25
Тогда мы сможем составить заговор с geom_polygon
:
ggplot(df)
geom_tile(aes(x = Truth, y = Prediction, fill = Data_Set))
geom_polygon(aes(x = polyx, y = polyy, group = observation, fill = Data_Set),
color = "gray30")
geom_text(aes(x = x, y = y, label = Value), check_overlap = TRUE)
scale_fill_manual(values = c("#a7ca88", "#b4c7e7", "#f4b184", "#fdda65"))
coord_equal()
Комментарии:
1. Большое спасибо! Это действительно хорошее решение. Обработка полигонов заняла бы у меня целую вечность. Я попытался использовать циклы for для координат многоугольника, но заблудился в промежутке, пытаясь понять, как объединить мои данные и позиции многоугольника.