将绘图对象存储在列表中

发布于 2024-08-13 03:58:01 字数 2037 浏览 1 评论 0原文

昨天我问了这个关于在对象中存储绘图的问题。我尝试实现第一种方法(注意我没有指定我在原始问题中使用 qplot() ),并注意到它没有按预期工作。

library(ggplot2)               # add ggplot2

string = "C:/example.pdf"      # Setup pdf
pdf(string,height=6,width=9)

x_range <- range(1,50)         # Specify Range

# Create a list to hold the plot objects.
pltList <- list()
pltList[]

for(i in 1 : 16){

# Organise data 
y = (1:50) * i * 1000                       # Get y col
x = (1:50)                                  # get x col
y = log(y)                                  # Use natural log

# Regression
lm.0 = lm(formula = y ~ x)                  # make linear model
inter = summary(lm.0)$coefficients[1,1]     # Get intercept
slop = summary(lm.0)$coefficients[2,1]      # Get slope

# Make plot name
pltName <- paste( 'a', i, sep = '' )

# make plot object    
p <- qplot(
    x, y,   
    xlab = "Radius [km]", 
    ylab = "Services [log]",
    xlim = x_range,
    main = paste("Sample",i)
) + geom_abline(intercept = inter, slope = slop, colour = "red", size = 1)        

print(p)     

pltList[[pltName]] = p       
}

# close the PDF file
dev.off() 

在本例中我使用了示例编号,因此如果只是复制代码,代码就会运行。我确实花了几个小时对此感到困惑,但我无法弄清楚出了什么问题。它可以毫无问题地编写第一组 pdf,因此我有 16 个带有正确绘图的 pdf。

然后,当我使用这段代码时:

string = "C:/test_tabloid.pdf"
pdf(string, height = 11, width = 17)

grid.newpage()
pushViewport( viewport( layout = grid.layout(3, 3) ) )

vplayout <- function(x, y){viewport(layout.pos.row = x, layout.pos.col = y)}

counter = 1

# Page 1
for (i in 1:3){    
    for (j in 1:3){     
         pltName <- paste( 'a', counter, sep = '' )   
         print( pltList[[pltName]], vp = vplayout(i,j) )
         counter = counter + 1
     }
 }

 dev.off()

我得到的结果是每个图形上的最后一个线性模型线(abline),但数据没有改变。当我检查绘图列表时,似乎所有绘图都被最新的绘图覆盖(除了 abline 对象)。

一个不太重要的次要问题是如何生成每页上有多个绘图的多页 pdf,但我的代码的主要目标是将绘图存储在我以后可以访问的列表中。

I asked this question yesterday about storing a plot within an object. I tried implementing the first approach (aware that I did not specify that I was using qplot() in my original question) and noticed that it did not work as expected.

library(ggplot2)               # add ggplot2

string = "C:/example.pdf"      # Setup pdf
pdf(string,height=6,width=9)

x_range <- range(1,50)         # Specify Range

# Create a list to hold the plot objects.
pltList <- list()
pltList[]

for(i in 1 : 16){

# Organise data 
y = (1:50) * i * 1000                       # Get y col
x = (1:50)                                  # get x col
y = log(y)                                  # Use natural log

# Regression
lm.0 = lm(formula = y ~ x)                  # make linear model
inter = summary(lm.0)$coefficients[1,1]     # Get intercept
slop = summary(lm.0)$coefficients[2,1]      # Get slope

# Make plot name
pltName <- paste( 'a', i, sep = '' )

# make plot object    
p <- qplot(
    x, y,   
    xlab = "Radius [km]", 
    ylab = "Services [log]",
    xlim = x_range,
    main = paste("Sample",i)
) + geom_abline(intercept = inter, slope = slop, colour = "red", size = 1)        

print(p)     

pltList[[pltName]] = p       
}

# close the PDF file
dev.off() 

I have used sample numbers in this case so the code runs if it is just copied. I did spend a few hours puzzling over this but I cannot figure out what is going wrong. It writes the first set of pdfs without problem, so I have 16 pdfs with the correct plots.

Then when I use this piece of code:

string = "C:/test_tabloid.pdf"
pdf(string, height = 11, width = 17)

grid.newpage()
pushViewport( viewport( layout = grid.layout(3, 3) ) )

vplayout <- function(x, y){viewport(layout.pos.row = x, layout.pos.col = y)}

counter = 1

# Page 1
for (i in 1:3){    
    for (j in 1:3){     
         pltName <- paste( 'a', counter, sep = '' )   
         print( pltList[[pltName]], vp = vplayout(i,j) )
         counter = counter + 1
     }
 }

 dev.off()

the result I get is the last linear model line (abline) on every graph, but the data does not change. When I check my list of plots, it seems that all of them become overwritten by the most recent plot (with the exception of the abline object).

A less important secondary question was how to generate a muli-page pdf with several plots on each page, but the main goal of my code was to store the plots in a list that I could access at a later date.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

旧人 2024-08-20 03:58:01

好的,如果您的绘图命令更改为,

p <- qplot(data = data.frame(x = x, y = y),
           x, y,   
           xlab = "Radius [km]", 
           ylab = "Services [log]",
           xlim = x_range,
           ylim = c(0,10),
           main = paste("Sample",i)
           ) + geom_abline(intercept = inter, slope = slop, colour = "red", size = 1)           

那么一切都会按预期进行。这就是我怀疑正在发生的事情(尽管哈德利可能会澄清事情)。当 ggplot2“保存”数据时,它实际上所做的是保存数据框和参数名称。因此,对于我给出的命令,您会得到

> summary(pltList[["a1"]])
data: x, y [50x2]
mapping:  x = x, y = y
scales:   x, y 
faceting: facet_grid(. ~ ., FALSE)
-----------------------------------
geom_point:  
stat_identity:  
position_identity: (width = NULL, height = NULL)

mapping: group = 1 
geom_abline: colour = red, size = 1 
stat_abline: intercept = 2.55595281266726, slope = 0.05543539319091 
position_identity: (width = NULL, height = NULL)

然而,如果您没有在 qplot 中指定 data 参数,则所有变量都会在当前范围内求值,因为没有附加(读取:已保存)数据框。

data: [0x0]
mapping:  x = x, y = y
scales:   x, y 
faceting: facet_grid(. ~ ., FALSE)
-----------------------------------
geom_point:  
stat_identity:  
position_identity: (width = NULL, height = NULL)

mapping: group = 1 
geom_abline: colour = red, size = 1 
stat_abline: intercept = 2.55595281266726, slope = 0.05543539319091 
position_identity: (width = NULL, height = NULL)

因此,当第二次生成绘图时,它不使用原始值,而是使用 xy当前值。

Ok, so if your plot command is changed to

p <- qplot(data = data.frame(x = x, y = y),
           x, y,   
           xlab = "Radius [km]", 
           ylab = "Services [log]",
           xlim = x_range,
           ylim = c(0,10),
           main = paste("Sample",i)
           ) + geom_abline(intercept = inter, slope = slop, colour = "red", size = 1)           

then everything works as expected. Here's what I suspect is happening (although Hadley could probably clarify things). When ggplot2 "saves" the data, what it actually does is save a data frame, and the names of the parameters. So for the command as I have given it, you get

> summary(pltList[["a1"]])
data: x, y [50x2]
mapping:  x = x, y = y
scales:   x, y 
faceting: facet_grid(. ~ ., FALSE)
-----------------------------------
geom_point:  
stat_identity:  
position_identity: (width = NULL, height = NULL)

mapping: group = 1 
geom_abline: colour = red, size = 1 
stat_abline: intercept = 2.55595281266726, slope = 0.05543539319091 
position_identity: (width = NULL, height = NULL)

However, if you don't specify a data parameter in qplot, all the variables get evaluated in the current scope, because there is no attached (read: saved) data frame.

data: [0x0]
mapping:  x = x, y = y
scales:   x, y 
faceting: facet_grid(. ~ ., FALSE)
-----------------------------------
geom_point:  
stat_identity:  
position_identity: (width = NULL, height = NULL)

mapping: group = 1 
geom_abline: colour = red, size = 1 
stat_abline: intercept = 2.55595281266726, slope = 0.05543539319091 
position_identity: (width = NULL, height = NULL)

So when the plot is generated the second time around, rather than using the original values, it uses the current values of x and y.

鱼忆七猫命九 2024-08-20 03:58:01

我认为您应该在 qplot 中使用 data 参数,即将向量存储在数据框中。

请参阅 Hadley 的书,第 4.4 节:

对数据的限制很简单:它必须是一个数据框。这是有限制的,与 R 中的其他图形包不同。Lattice 函数可以采用可选的数据帧或直接使用来自全局环境的向量。 ...

数据作为副本而不是引用存储在绘图对象中。这个有两个
重要后果:如果您的数据发生变化,绘图不会发生变化; ggplot2 对象是完全独立的,因此可以将它们保存到磁盘,然后加载并绘制,而不需要该会话中的任何其他内容。

I think you should use the data argument in qplot, i.e., store your vectors in a data frame.

See Hadley's book, Section 4.4:

The restriction on the data is simple: it must be a data frame. This is restrictive, and unlike other graphics packages in R. Lattice functions can take an optional data frame or use vectors directly from the global environment. ...

The data is stored in the plot object as a copy, not a reference. This has two
important consequences: if your data changes, the plot will not; and ggplot2 objects are entirely self-contained so that they can be save()d to disk and later load()ed and plotted without needing anything else from that session.

最佳男配角 2024-08-20 03:58:01

您的代码中存在有关列表下标的错误。 应该

pltList[[pltName]]

pltList[pltName]

注意:

class(pltList[1])
[1] "list"

pltList[1]是一个包含pltList第一个元素的列表

class(pltList[[1]])
[1] "ggplot"

pltList[[1]] 是 pltList 的第一个元素

There is a bug in your code concerning list subscripting. It should be

pltList[[pltName]]

not

pltList[pltName]

Note:

class(pltList[1])
[1] "list"

pltList[1] is a list containing the first element of pltList.

class(pltList[[1]])
[1] "ggplot"

pltList[[1]] is the first element of pltList.

落叶缤纷 2024-08-20 03:58:01

对于你的第二个问题:多页 pdf 很容易 - 请参阅 help(pdf)

 onefile: logical: if true (the default) allow multiple figures in one
          file.  If false, generate a file with name containing the
          page number for each page.  Defaults to ‘TRUE’.

对于你的主要问题,我不明白你是否想存储绘图输入 在列表中供以后处理,或绘图输出。如果是后者,我不确定 plot() 返回一个可以存储和检索的对象。

For your second question: Multi-page pdfs are easy -- see help(pdf):

 onefile: logical: if true (the default) allow multiple figures in one
          file.  If false, generate a file with name containing the
          page number for each page.  Defaults to ‘TRUE’.

For your main question, I don't understand if you want to store the plot inputs in a list for later processing, or the plot outputs. If it is the latter, I am not sure that plot() returns an object you can store and retrieve.

表情可笑 2024-08-20 03:58:01

关于第二个问题的另一个建议是使用 Sweave 或 Brew,因为它们可以让您完全控制如何显示多页 pdf。

查看此相关问题

Another suggestion regarding your second question would be to use either Sweave or Brew as they will give you complete control over how you display your multi-page pdf.

Have a look at this related question.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文