Как объединить цвета, стиль и легенды формы в ggplot

Предположим, у меня есть следующий график в ggplot:

График ggplot

Он был сгенерирован с использованием следующего кода:

x <- seq(0, 10, by = 0.2) y1 <- sin(x) y2 <- cos(x) y3 <- cos(x + pi / 4) y4 <- sin(x + pi / 4) df1 <- data.frame(x, y = y1, Type = as.factor("sin"), Method = as.factor("method1")) df2 <- data.frame(x, y = y2, Type = as.factor("cos"), Method = as.factor("method1")) df3 <- data.frame(x, y = y3, Type = as.factor("cos"), Method = as.factor("method2")) df4 <- data.frame(x, y = y4, Type = as.factor("sin"), Method = as.factor("method2")) df.merged <- rbind(df1, df2, df3, df4) ggplot(df.merged, aes(x, y, colour = interaction(Type, Method), linetype = Method, shape = Type)) + geom_line() + geom_point() 

Я хотел бы иметь только одну легенду, которая правильно отображает фигуры, цвета и типы линий (легенды взаимодействия (тип, метод) наиболее близки к тому, что я хотел бы, но у них нет правильных форм / типов линий) ,

Я знаю, что если я использую scale_xxx_manual, и я укажу те же метки для всех легенд, они будут объединены, но я не хочу устанавливать метки вручную: если есть новые методы или типы, я не хочу иметь изменить мой код : нужно что-то общее.

редактировать

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

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

 y5 <- sin(x - pi / 4) df5 <- data.frame(x, y = y5, Type = as.factor("sin"), Method = as.factor("method3")) df.merged <- rbind(df1, df2, df3, df4, df5) override.shape <- c(16, 17, 16, 17, 16) override.linetype <- c(1, 1, 3, 3, 4) g <- ggplot(df.merged, aes(x, y, colour = interaction(Type, Method), linetype = Method, shape = Type)) + geom_line() + geom_point() g <- g + guides(colour = guide_legend(override.aes = list(shape = override.shape, linetype = override.linetype))) g <- g + scale_shape(guide = FALSE) g <- g + scale_linetype(guide = FALSE) print(g) 

Это дает:

5 кривых

Теперь возникает вопрос: как автоматически генерировать векторы override.shape и override.linetype ?

Обратите внимание, что размер вектора равен 5, потому что у нас есть 5 кривых, а коэффициент interaction(Type, Method) имеет размер 6 (у меня нет данных для комбинации cos / method3)

У меня была эта проблема на днях. Раздел R Cookbook в разделе « Легенды» объясняет:

Если вы используете как цвет, так и форму, им нужно дать спецификации масштаба. В противном случае будет две две отдельные легенды.

В вашем случае вам нужны спецификации для shape и linetype .

редактировать

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

Если вам нужна подробная схема всех возможных форм и типов линий, проверьте этот сайт R Graphics, чтобы увидеть все идентификаторы номеров:

 df.merged$int <- paste(df.merged$Type, df.merged$Method, sep=".") ggplot(df.merged, aes(x, y, colour = int, linetype=int, shape=int)) + geom_line() + geom_point() + scale_colour_discrete("") + scale_linetype_manual("", values=c(1,2,1,2)) + scale_shape_manual("", values=c(17,17,16,16)) 

введите описание изображения здесь

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

 p = ggplot(df.merged, aes(x, y, colour=interaction(Type, Method), linetype=interaction(Type, Method), shape=interaction(Type, Method))) + geom_line() + geom_point() p + scale_shape_manual(values=rep(16:17, 2)) + scale_linetype_manual(values=rep(c(1,3),each=2)) 

введите описание изображения здесь

Вот решение в общем случае:

 # Create the data frames x <- seq(0, 10, by = 0.2) y1 <- sin(x) y2 <- cos(x) y3 <- cos(x + pi / 4) y4 <- sin(x + pi / 4) y5 <- sin(x - pi / 4) df1 <- data.frame(x, y = y1, Type = as.factor("sin"), Method = as.factor("method1")) df2 <- data.frame(x, y = y2, Type = as.factor("cos"), Method = as.factor("method1")) df3 <- data.frame(x, y = y3, Type = as.factor("cos"), Method = as.factor("method2")) df4 <- data.frame(x, y = y4, Type = as.factor("sin"), Method = as.factor("method2")) df5 <- data.frame(x, y = y5, Type = as.factor("sin"), Method = as.factor("method3")) # Merge the data frames df.merged <- rbind(df1, df2, df3, df4, df5) # Create the interaction type.method.interaction <- interaction(df.merged$Type, df.merged$Method) # Compute the number of types and methods nb.types <- nlevels(df.merged$Type) nb.methods <- nlevels(df.merged$Method) # Set the legend title legend.title <- "My title" # Initialize the plot g <- ggplot(df.merged, aes(x, y, colour = type.method.interaction, linetype = type.method.interaction, shape = type.method.interaction)) + geom_line() + geom_point() # Here is the magic g <- g + scale_color_discrete(legend.title) g <- g + scale_linetype_manual(legend.title, values = rep(1:nb.types, nb.methods)) g <- g + scale_shape_manual(legend.title, values = 15 + rep(1:nb.methods, each = nb.types)) # Display the plot print(g) 

В результате получается следующее:

Решение

  • Кривые синуса рисуются сплошными линиями и кривыми косинуса как пунктирные линии.
  • Данные «method1» используют заполненные круги для формы.
  • «method2» использует треугольник для формы.
  • Данные «method3» используют заполненные алмазы для формы.
  • Легенда соответствует кривой

Подводя итог, трюки:

  • Используйте interaction Тип / Метод для всех представлений данных (цвет, форма, тип линии и т. Д.).
  • Затем вручную задайте стили кривой и стили легенд с помощью scale_xxx_manual .
  • scale_xxx_manual позволяет вам предоставить вектор значений, который больше, чем фактическое число кривых, поэтому легко вычислить значения вектора стиля из размеров факторов типа и метода

Нужно просто назвать оба направителя одинаковыми. Например:

 g+ scale_linetype_manual(name="Guide1",values= c('solid', 'solid', 'dotdash'))+ scale_colour_manual(name="Guide1", values = c("blue", "green","red")) 

Используйте labs() и установите одинаковое значение для всей эстетики, определяющей внешний вид геометрий.

 library('ggplot2') ggplot(iris) + aes(x = Sepal.Length, y = Sepal.Width, color = Species, linetype = Species, shape = Species) + geom_line() + geom_point() + labs(color = "Guide name", linetype = "Guide name", shape = "Guide name") 

  • Удалить кавычки из символьного вектора в R
  • Где R хранит пакеты?
  • Объедините неравные данные и замените отсутствующие строки на 0
  • Точное хранение больших целых чисел
  • Построение графика во время цикла в RStudio
  • Существует ли R-функция для нахождения индекса элемента в векторе?
  • Как назначить функцию, возвращающую более одного значения?
  • Частота отсчета в R
  • Использование списков внутри столбцов data.table
  • Проверьте установленные пакеты перед запуском install.packages ()
  • Создайте последовательность последнего дня месяца в течение двух лет
  • Interesting Posts

    Загрузить / Поток файла из URL-адреса – asp.net

    Ошибка: allowDefinition = ‘MachineToApplication’ за пределами уровня приложения

    Как иметь два заголовка на одном уровне в многоуровневом списке?

    javax.net.ssl.SSLException: Ошибка чтения: ssl = 0x9524b800: ошибка ввода-вывода во время системного вызова, сброс соединения с помощью одноранговой сети

    Настроить Android Intent.ACTION_SEND

    Proguard вызывает RuntimeException (Unmarshalling неизвестный тип кода) в classе Parcelable

    средняя точка между двумя широтами и долготой

    Невозможно указать модификатор «async» в методе «Основной» консольного приложения

    CruiseControl против TeamCity для непрерывной интеграции?

    В C #, почему String является ссылочным типом, который ведет себя как тип значения?

    Android / iOS – настройка пользовательского URI / протокола

    Прокрутка AutoHotkey и средний щелчок и ускорение мыши

    Что такое ассоциативность операторов и почему это важно?

    Сокращение, чтобы проверить, существует ли объект в массиве для Swift?

    grep с использованием символьного вектора с несколькими шаблонами

    Давайте будем гением компьютера.