2017-02-14 15 views
0

У меня очень простая петля, которая пытается нарисовать четыре кривые на одном графике, используя ggplot. Вот код:кривые добавления цикла ggplot не работают, но работают по одному

df = data.frame(x=0:10/10) 
    gg = ggplot(df) 
    for (t in 4:1/4) 
     gg = gg + geom_path(aes(x,x^t)) 
    gg 

Когда я запустил его, он отображает только последний график. Если я добавлю их по одному, например:

df = data.frame(x=0:10/10) 
    gg = ggplot(df) 
    gg = gg + geom_path(aes(x,x^1.00)) 
    gg = gg + geom_path(aes(x,x^0.75)) 
    gg = gg + geom_path(aes(x,x^0.50)) 
    gg = gg + geom_path(aes(x,x^0.25)) 
    gg 

он работает нормально. Может ли кто-нибудь объяснить магию?

+1

Вам необходимо захватить окружающую среду (текущее значение t на каждом этапе), в противном случае только последний будет существовать к моменту, когда ggplot2 фактически построит график – baptiste

+0

Вы проверили это [решение] (http://stackoverflow.com/вопросы/26235825/для цикла только-добавляет-на-конечный-ggplot-слой)? –

ответ

4

Baptiste предложил создать всю data.frame со всеми переменными, а затем построить ее (желательно в длинном формате) , answer provided by Gene создает данные в в широком формате, требующие петли над столбцами.

ниже код создает данные в длинном формате и графиков все кривые в одном вызове:

# create data in long format 
df <- expand.grid(x = 0:10/10, exp = 1:4/4) 
df$y <- df$x^df$exp 

# plot 
library(ggplot2) 
gg <- ggplot(df, aes(x, y, group = exp)) + geom_line() 
gg 

enter image description here

Обратите внимание, что geom_line() используется здесь, потому что она соединяет наблюдения в порядке переменной на ось х. geom_path() соединяет наблюдения в том порядке, в котором они отображаются в данных.

Различные кривые могут быть цвет, а также:

# continous scale 
gg + aes(colour = exp) 

enter image description here

# discrete scale 
gg + aes(colour = factor(exp)) 

enter image description here

Обратите внимание, что, в том числе цвета эстетики в вызове aes() соответствующая легенда создается по умолчанию.

+0

Я принял это, хотя ответ by @baptiste короткий и говорит больше. Это было настолько кратким, что я не мог понять, что означало длинный формат и широкий, пока я не увидел другого ответа. –

4

вы могли substitute the value явно

eval(substitute(expr = {gg = gg + geom_path(aes(x,x^t))}, env = list(t=t))) 

, но лучшим решением было бы создать весь data.frame со всеми переменными, а затем построить его (желательно в длинном формате).

1

Как указано в пункте solution, циферблат for не работает из-за ленивой оценки. Вот рабочий цикл for, который работает, обновляя предоставленные данные в каждом цикле. Как уже отмечалось, существуют более эффективные способы для построения этого

#make the data and put it all into a single df 
df = data.frame(x=0:10/10) 
df = cbind(df,sapply(4:1/4, function(t) df$x^t)) 

# initiate ggplot 
g <- ggplot(df) 

# make some colours 
cols = colorRampPalette(c("blue",'green'))(ncol(df)) 

# loop over columns 
for (j in 2:ncol(df)){ 

    # update the data within the loop 
    gg.data <- data.frame(x = df[,1], y = df[,j]) 

    # add the line 
    g <- g + geom_path(data = gg.data, aes(x,y), col = cols[j]) 
} 
g 

g plot

+3

@Baptiste предложил создать данные в _long формате_. Ваш ответ создает данные в _wide формате_, что менее предпочтительно для 'ggplot2' и требует ненужного перебора столбцов. Поэтому ваше утверждение «Правильный подход» довольно силен. – Uwe

+0

@UweBlock, в некоторых случаях, таких как ссылка на решение, цикл for неизбежен. Более того, ОП был обеспокоен тем, почему цикл for не работал, следовательно, ответ. Если бы это был мой код, я бы поместил данные в длинный формат и пусть ggplot позаботится о деталях. –

+0

Я согласен, что для циклов нельзя избежать несколько раз. Но они не являются надлежащим решением ни в этом случае, ни в связанном решении, потому что весь подход в обоих случаях был ошибочным. Для меня оба случая: [_XY problems_] (http://xyproblem.info/). Оба OP столкнулись с проблемой добавления слоев в объект ggplot в цикле for, потому что они не создали данные в формате, который предпочитает ggplot. Лучший вопрос был бы, например, «Как подготовить данные для построения параметризованных кривых с помощью ggplot?». – Uwe