如何使用少量命令绘制漂亮的图形,将绘图逻辑与布局分开?

时间:2010-01-09 17:40:22

标签: graphics r plot

有没有一种简单的方法可以在R中创建以下数据的漂亮图,而不使用很多命令?

 Region1 Region2
2007 17 55
2008 26 43
2009 53 70
2010 96 58

我确实知道如何绘制数据,但它使用了太多的命令和参数,结果看起来仍然非常糟糕(参见here):

> test <- read.table("/tmp/data.txt")
> png(filename="/tmp/test.png", height=1000, width=750, bg="white", res=300)
> plot(test$Region1, type="b", col="blue", ylim=c(0,100), lwd=3)
> lines(test$Region2, type="b", col="red", lwd=3)
> dev.off()

我花了一段时间才弄清楚所有命令,我仍然需要使用axis命令获取x轴标签(2007年,2008年......)(但我如何访问test x轴标签?)等。

在Keynote(或Powerpoint)中,我可以给它相同的表(转置)并从中生成一个漂亮的图形(参见here)。

我的问题是:是否有更高级别的命令可以很好地绘制这些典型数据?另外,如何从布局中分离绘图逻辑(从特定数据中绘制2条线等)(使用图形的特定颜色和线条类型等)?理想情况下,我希望图表的不同布局有不同的库,例如叫NiceKeynoteLayout,我可以像这样(或类似)使用:

> d <- read.table("/tmp/data.txt")
> png <- png(filename="/tmp/test.png", height=1000, width=750)
> myLayout <- loadPredefinedLayout("NiceKeynoteLayout")
> coolplot(d, layout=myLayout, out=png)

4 个答案:

答案 0 :(得分:3)

是的,根据我的偏见,你最好使用ggplot2包来创建图形。以下是您使用数据的方式(感谢Dirk提供样本数据集)

data <- data.frame(Year=seq(as.Date("2007-01-01"), 
                   as.Date("2010-01-01"), by="year"), 
                 Region1=c(17,26,53,96), Region2=c(55,43,70,58))

library(ggplot2)

# Convert data to a form optimised for visualisation, not
# data entry
data2 <- melt(data, measure = c("Region1", "Region2"))

# Define the visualisation you want
ggplot(data2, aes(x = Year, y = value, colour = variable)) + 
  geom_line()

答案 1 :(得分:2)

这是R代码,它以一种很好的方式绘制数据(它不是所要求的简单代码,但至少结果看起来不错):

test <- read.table("/tmp/test.txt", header=TRUE)
png(filename="/tmp/test.png", height=750, width=1000, 
    bg="white", res=300)
par(mar=c(2.5,2.5,0.75,0.75), 
    family="Gill Sans", font=1, # font 2 would be bold
    cex=0.75, cex.lab=0.75, cex.axis=0.75) 
mymax <- max(test$Region1, test$Region2)*1.25

plot(test$Region1, type="b", col="#304E67", 
     ylim=c(0, mymax), lwd=3,
     bty="l", axes=FALSE, ann=FALSE, cex=1.0, tck=1)

axis(1, lwd.ticks=0, at=1:length(test$Year), lab=test$Year)
axis(2, lwd=0, las=1, at=c(0,25,50,75,100), yaxp=c(0,100,4))
# grid(nx = NA, ny = 5, col = "lightgray") # wrong, see axTicks
for(y in c(25, 50, 75, 100)) {
  lines(rep(y, length(test$Region1)), type="l", col="lightgray", lwd=1)
}

lines(test$Region1, type="b", col="#304E67", lwd=3)
lines(test$Region2, type="b", col="#974449", lwd=3)

# title(xlab="Year", col.lab=rgb(0,0.5,0))
# title(ylab="Output", col.lab=rgb(0,0.5,0))
legend(1, mymax+8, c("Region 1","Region 2"), cex=0.75, 
       col=c("#304E67" ,"#974449"), 
       pch=1:1, # circles
       lty=1:1, # solid 
       lwd=1.5, # line width
       bty="n") # no box around

dev.off()

数据文件包含以下内容:

Year Region1 Region2
2007 17 55
2008 26 43
2009 53 70
2010 96 58

它生成以下图表: http://i46.tinypic.com/206gchk.png/

非常接近Keynote绘制的图表:

答案 2 :(得分:0)

您可能希望阅读help(par),这是自定义标准R图的非常有用的信息来源。这允许你

  • 有更紧密的外边距(例如par(mar=c(3,3,1,1)
  • 更改字体(例如par(cex=0.7)或某些更具体的cex替代品
  • 设置颜色或线型
  • ...

所有这些都接近您想要的loadPredefinedLayout()功能。

最后,对于轴,您最好使用时间感知类(如zoo),或者显式给出x轴参数,如下例所示:

R> data <- data.frame(Year=seq(as.Date("2007-01-01"), \
                   as.Date("2010-01-01"), by="year"), \
                 Region1=c(17,26,53,96), Region2=c(55,43,70,58))
R> data
        Year Region1 Region2
1 2007-01-01      17      55
2 2008-01-01      26      43
3 2009-01-01      53      70
4 2010-01-01      96      58
R> par(mar=c(3,4,1,1)) 
R> plot(data$Year, data$Region1, type='l', col='blue', ylab="Values")
R> lines(data$Year, data$Region2, col='red')
R> 

答案 3 :(得分:0)

A(在我看来)Hadley建议的图形略有改进版本。我认为现在它非常类似于您尝试复制的原始图形(实际上,使用直接标签更好)。

按照Hadley的建议转换数据后,

plot <- ggplot(data2, aes(Year, value, group = variable,
     colour = variable)) + geom_line(size = 1) +
     opts(legend.position = "none")
plot <- plot + geom_point () + opts(legend.position = "none")
plot + geom_text(data = data2[data2$year == 2010,
     ], aes(label = variable), hjust = 1.2, vjust = 1)