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

发布于 2024-08-17 04:18:37 字数 1217 浏览 2 评论 0原文

有没有一种简单的方法可以在 R 中绘制以下数据的漂亮图,而无需使用许多命令?

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

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

> 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,...) code> 命令(但如何访问 test x 轴标签?)等。

在 Keynote(或 Powerpoint)中,我可以给它相同的表格(转置),它会生成一个漂亮的图表(请参阅此处)。

我的问题确实是:是否有更高级别的命令可以很好地绘制此类典型数据?另外,如何将绘图逻辑(从特定数据中绘制 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)

Is there a simple way to make a nice plot of the following data in R, without using many commands?

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

I do know how to plot the data, but it uses too many commands and parameters, and the result still looks absolutely terrible (see 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()

It took me a while to figure out all the commands, and I still have to get the x axis labels (2007, 2008, ...), using the axis command (but how do I access the test x axis labels?), etc.

In Keynote (or Powerpoint) I can just give it the same table (transposed) and it produces a nice graph from it (see here).

My question is really: Is there a higher-level command that draws such typical data nicely? Also, how can I separate the drawing logic (draw 2 lines from that specific data, etc.) from the layout (use specific colors and line types for the graph, etc.)? Ideally, I'd hope there were different libraries for different layouts of the graph, e.g. called NiceKeynoteLayout, which I just could use like this (or similar):

> 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)

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

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

发布评论

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

评论(4

梦里人 2024-08-24 04:18:37

是的,在我看来,您最好使用 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()

Yes, and in my biased opinion, you're best off using the ggplot2 package for creating graphics. Here's how you might do so with your data (thanks to Dirk for providing a sample datset)

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()
口干舌燥 2024-08-24 04:18:37

这是以一种很好的方式绘制数据的 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

它生成以下图表:

这与 Keynote 绘制的图表非常接近:

Here is R code that plots the data in a nice way (it is not simple code as requested, but at least the result looks good):

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()

The data file has this content:

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

It produces the following graph:

which comes pretty close to the graph that Keynote draws:

冷弦 2024-08-24 04:18:37

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

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

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

最后,对于轴,您最好使用时间。 -aware 类,如 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> 

You may want to read up on help(par) which is a very useful source of information for customizing standard R graphs. This allows you to

  • have tighter outer margins (eg par(mar=c(3,3,1,1))
  • change fonts (eg par(cex=0.7) or some of the more specific cex alternatives
  • set colors or linetypes
  • ...

all of which comes close to your desired loadPredefinedLayout() functionality you desire.

Lastly, for the axes you are better off to either use a time-aware class like zoo, or to explicit give the x-axis argument as in the example below:

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> 
假情假意假温柔 2024-08-24 04:18:37

(在我看来)哈德利建议的图形的略微改进版本。我认为现在它非常像您尝试复制的原始图形(实际上,使用直接标签更好)。

按照哈德利的建议转换数据后,

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)

A (in my opinion) slightly improved version of the graphic suggested by Hadley. I think now it is pretty much like the original graphic you tried to replicate (even better, actually, with direct labels).

After converting the data as suggested by 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)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文