Базовая графика в R плоха для печати (если честно, можно было получше выбрать значения по умолчанию). В целом, эти функции для некоторых — признак заката эры R. Думаю, большинство людей согласится, что есть в R графические функции и получше (например, ggplot2). Но иногда бывет целесообразно сделать график именно с помощью базовых функций. Например, если графика в вашей публикации должна быть воспроизводима даже спустя пять лет.

В этом посте рассмотрим методы, позволяющие кардинально изменить внешний вид базовой графики в R. С некоторыми (окей, иногда большими) усилиями можно изменить все параметры графика именно так, как вам нужно.

Обычно я терпеть не могу использовать набор данных iris. Наверное, это самый используемый набор в мире R. Именно поэтому возьмем его в этом посте для демонстрации всех возможностей.

Стандартная диаграмма рассеивания в R:

plot(iris$Sepal.Length, iris$Sepal.Width, col = iris$Species)
legend("topright", legend = levels(iris$Species), col = 1:3, pch = 21)



Это дает простую диаграмму рассеивания с легендой и цветовой схемой по умолчанию. Список того, что не так с этим графиком, довольно длинный, в том числе и:

  • цвета
  • отступы
  • подписи осей
  • пересекающиеся точки
  • пустое пространство

Но даже в базовой графической системе R можно все это исправить!

Исправляем проблемы


Первая проблема этой диаграммы рассеивания — некоторые точки друг на друге. Поэтому первый шаг — расставить точки подальше так, чтобы они не наслаивались — функция jitter() поможет.

## То же, что и geom_jitter
iris$Sepal.Length = jitter(iris$Sepal.Length)
iris$Sepal.Width = jitter(iris$Sepal.Width)

Теперь выберем цвета получше (я выбрал палитру с этого сайта). Функция palette() позволяет глобально изменить палитру цветов для базовых графиков R.

alpha = 150 # Прозрачные точки
palette(c(rgb(200, 79, 178, alpha = alpha, maxColorValue = 255), 
          rgb(105, 147, 45, alpha = alpha, maxColorValue = 255),
          rgb(85, 130, 169, alpha = alpha, maxColorValue = 255)))

Теперь несколько характеристик графика — функция par():

par(mar = c(3, 3, 2, 1), # Расстояние от графика до края страницы
    mgp = c(2, 0.4, 0), # Расстояние от графика до подписи
    las = 1, # Повернуть подпись оси у
    tck = -.01, # Уменьшить толщину отметок
    xaxs = "i", yaxs = "i") # Убрать отступы внутри графика

Теперь очередь собственно функции plot(). Были цветочки, а это ягодки. Мы создаем график функцией plot() со множеством аргументов:

plot(iris$Sepal.Length, iris$Sepal.Width, 
     bg = iris$Species, # Цвет заливки
     pch = 21, # Форма: кружки с возможностью заливки
     xlab = "Sepal Length", ylab = "Sepal Width", # Подписи
     axes = FALSE, # Не рисовать оси
     frame.plot = FALSE, # Убрать рамочку 
     xlim = c(4, 8), ylim = c(2, 4.5), # Границы
     panel.first = abline(h = seq(2, 4.5, 0.5), col = "grey80"))

Добавим отметки на оси х:

at = pretty(iris$Sepal.Length)
mtext(side = 1, text = at, at = at, 
      col = "grey20", line = 1, cex = 0.9)

и оси у:

at = pretty(iris$Sepal.Width)
mtext(side = 2, text = at, at = at, col = "grey20", line = 1, cex = 0.9)

Осталась только легенда. Но вместо того, чтобы воспользоваться функцией legend(), выведем названия возле точек с функцией text().

text(5, 4.2, "setosa", col = rgb(200, 79, 178, maxColorValue = 255))
text(5.3, 2.1, "versicolor", col = rgb(105, 147, 45, maxColorValue = 255))
text(7, 3.7, "virginica", col = rgb(85, 130, 169, maxColorValue = 255))

Наконец, заголовок графика:

title("The infamous IRIS data", adj = 1, 
      cex.main = 0.8, font.main = 2, col.main = "black")

Все вместе:



Гораздо лучше.

Почему не ggplot2 (или что-то другое)?


Кажется, что создать простую диаграмму рассеивания — куча работы. Почему же не использовать X, Y или ggplot2? Основное преимущество, которое вы получаете — ваш график будет почти наверняка воспроизводим во всех будущих версиях R. Серьезная заявка.

Комментарии (4)


  1. Alexey_mosc
    29.01.2018 11:48

    Хорошо!


  1. Hardcoin
    29.01.2018 12:30

    А ggplot2 разве не будет в будущих версиях R?


  1. borisxm
    29.01.2018 13:45

    Даже возможная совместимость с будущими версиями не заставит меня рисовать графики стандартными средствами. Слегка обернутый ggplot2 полностью покрывает все потребности. Экосистема должна развиваться, а plot(), это стагнация.


  1. kxx
    29.01.2018 22:42

    А вот статья на тему, почему ggplot2 не так уж и хорош.
    P.S. В оригинальном тексте вроде бы нет никакого «признака заката эры R» — есть что-то типа возвращения к истокам, к тому состоянию, когда R только начинали использовать.