Как мне сделать мою линию лучше и аккуратнее? - PullRequest
4 голосов
/ 18 апреля 2020

Я пытаюсь сделать простой график со следующим кодом.

eta = c(0, 0.2, 0.4, 0.6, 0.8, 1)
R = c(0, 0.647058807, 0.864035125, 0.992063541, 0.996376783, 1)

p = as.data.frame(cbind(eta, R))

library(ggplot2)
ggplot(p) + 
geom_point(aes(x = eta, y = R), size = 3) +
geom_smooth(aes(y=R, x=eta), method = "loess", se = FALSE)

Я получаю график, подобный следующему:

Может ли функция geom_smooth принимать аргументы для изменения ширины или типа линии? Есть ли способ получить лучшее соответствие, чтобы кривая выглядела как хорошая непрерывная функция, подобная приведенной ниже?

Ответы [ 2 ]

4 голосов
/ 18 апреля 2020

Вы можете установить пользовательскую формулу в stat_smooth. Следуя вашему примеру, если вы хотите подогнать полином 4-го порядка, вы можете использовать

ggplot(p, aes(x = eta, y = R)) + 
  geom_point(size = 3) +
  stat_smooth(method = 'lm', formula = y~ poly(x, 4), se = FALSE)

enter image description here

Редактировать: добавление уравнения с асимптотой в 1,0. Это немного сложнее, так как требует решения с использованием нелинейного подхода. Три вещи, которые мне здесь помогли:

  • Следуя формуле nls в этом примере
  • Использование nls в stat_smooth, как они делают в этот ответ
  • Установите верхнюю границу равной 1,0 в соответствии с запросом ОП
ggplot(p, aes(x = eta, y = R)) + 
  geom_point(size = 3) +
  stat_smooth(method = 'nls', 
              formula = y ~ C*(1-exp(-k*x)),
              method.args = list(start=list(C=1,k=1),
                                 upper = c(C = 1, k = 10),
                                 algorithm = 'port'),
              se = FALSE)

enter image description here

Хотя это удобно для построения графиков, stat_smooth затрудняет доступ к формуле. Если вам это нужно, вы можете выйти за пределы графика, используя функцию nls напрямую, а затем делать прогнозы, используя predict.

# Fit model
fit_nls <-nls(R ~ C*(1-exp(-k*eta)), 
              data=p, 
              start=list(C=1,k=1), 
              upper = c(C = 1, k = 10), 
              algorithm = 'port')

# Predict model
df_pred <- data.frame(eta = seq(0,1.1,.01)) %>%
  mutate(R_pred = predict(fit_nls, newdata = .))

# Plot it
ggplot(p) + 
  geom_point(aes(x = eta, y = R), size = 3) +
  geom_line(data = df_pred, aes(x = eta, y = R_pred))
3 голосов
/ 18 апреля 2020

Вы можете изменить span подгонки, чтобы сделать ее более или менее гладкой. Вы также можете изменить ширину линии с помощью size и ввести с помощью linetype:

ggplot(p) + 
  geom_point(aes(x = eta, y = R), size = 3) +
  geom_smooth(
    aes(y=R, x=eta),
    method = "loess",
    se = FALSE, 
    span = 0.9, 
    linetype = "dashed",
    size = 0.5)

РЕДАКТИРОВАТЬ вот график: enter image description here

...