【问题标题】:Drawing a graph in the corner of another在另一个角落绘制图形
【发布时间】:2013-03-05 14:28:17
【问题描述】:

我应该如何在 R 中另一个图的角落呈现一个小图?

【问题讨论】:

  • 用ggplot2,见?annotation_custom中的最后一个例子

标签: r graphics plot


【解决方案1】:

我知道这个问题已经结束,但我将这个例子抛诸脑后。

一旦掌握了基础知识,您就可以使用基本的“网格”包非常轻松地进行这样的自定义可视化。这是我使用的一些自定义函数的快速示例以及绘制数据的演示。


自定义函数


# Function to initialize a plotting area.
init_Plot <- function(
    .df,
    .x_Loc, 
    .y_Loc, 
    .justify, 
    .width, 
    .height
    ){

    # Initialize plotting area to fit data.
    # We have to turn off clipping to make it
    # easy to plot the labels around the plot.
    pushViewport(viewport(xscale=c(min(.df[,1]), max(.df[,1])), yscale=c(min(0,min(.df[,-1])), max(.df[,-1])), x=.x_Loc, y=.y_Loc, width=.width, height=.height, just=.justify, clip="off", default.units="npc"))

    # Color behind text.
    grid.rect(x=0, y=0, width=unit(axis_CEX, "lines"), height=1, default.units="npc", just=c("right", "bottom"), gp=gpar(fill=space_Background, col=space_Background))
    grid.rect(x=0, y=1, width=1, height=unit(title_CEX, "lines"), default.units="npc", just=c("left", "bottom"), gp=gpar(fill=space_Background, col=space_Background))

    # Color in the space.
    grid.rect(gp=gpar(fill=chart_Fill, col=chart_Col))
}

# Function to finalize and label a plotting area.
finalize_Plot <- function(
    .df, 
    .plot_Title
    ){

    # Label plot using the internal reference
    # system, instead of the parent window, so
    # we always have perfect placement.
    grid.text(.plot_Title, x=0.5, y=1.05, just=c("center","bottom"), rot=0, default.units="npc", gp=gpar(cex=title_CEX))
    grid.text(paste(names(.df)[-1], collapse=" & "), x=-0.05, y=0.5, just=c("center","bottom"), rot=90, default.units="npc", gp=gpar(cex=axis_CEX))
    grid.text(names(.df)[1], x=0.5, y=-0.05, just=c("center","top"), rot=0, default.units="npc", gp=gpar(cex=axis_CEX))

    # Finalize plotting area.
    popViewport()
}

# Function to plot a filled line chart of
# the data in a data frame.  The first column
# of the data frame is assumed to be the
# plotting index, with each column being a
# set of y-data to plot.  All data is assumed
# to be numeric.
plot_Line_Chart <- function(
    .df,
    .x_Loc,
    .y_Loc,
    .justify,
    .width,
    .height,
    .colors,
    .plot_Title
    ){

    # Initialize plot.
    init_Plot(.df, .x_Loc, .y_Loc, .justify, .width, .height)

    # Calculate what value to use as the
    # return for the polygons.
    y_Axis_Min <- min(0, min(.df[,-1]))

    # Plot each set of data as a polygon,
    # so we can fill it in with color to
    # make it easier to read.
    for (i in 2:ncol(.df)){
        grid.polygon(x=c(min(.df[,1]),.df[,1], max(.df[,1])), y=c(y_Axis_Min,.df[,i], y_Axis_Min), default.units="native", gp=gpar(fill=.colors[i-1], col=.colors[i-1], alpha=1/ncol(.df)))
    }

    # Draw plot axes.
    grid.lines(x=0, y=c(0,1), default.units="npc")
    grid.lines(x=c(0,1), y=0, default.units="npc")

    # Finalize plot.
    finalize_Plot(.df, .plot_Title)

}

演示代码


grid.newpage()

# Specify main chart options.
chart_Fill = "lemonchiffon"
chart_Col = "snow3"
space_Background = "white"
title_CEX = 1.4
axis_CEX = 1

plot_Line_Chart(data.frame(time=1:1860, EuStockMarkets)[1:5], .x_Loc=1, .y_Loc=0, .just=c("right","bottom"), .width=0.9, .height=0.9, c("dodgerblue", "deeppink", "green", "red"), "EU Stocks")

# Specify sub-chart options.
chart_Fill = "lemonchiffon"
chart_Col = "snow3"
space_Background = "lemonchiffon"
title_CEX = 0.8
axis_CEX = 0.7

for (i in 1:4){
    plot_Line_Chart(data.frame(time=1:1860, EuStockMarkets)[c(1,i + 1)], .x_Loc=0.15*i, .y_Loc=0.8, .just=c("left","top"), .width=0.1, .height=0.1, c("dodgerblue", "deeppink", "green", "red")[i], "EU Stocks")
}

【讨论】:

  • 哇。相比之下,这绝对让我的反应看起来很弱。 :)
  • @TARehman 不过,主要区别在于您答案中的 par 方法可以接受基本绘图功能,而“网格”方法将要求您指定自己的绘图方法。这主要是一个时间问题,以及您的情节需要如何定制。
  • 问题没有结束,OP 绝对有能力改变他们对哪个答案获得复选标记的选择。
【解决方案2】:

我使用类似这样的方法完成了这项工作:

# Making some fake data
plot1 <- data.frame(x=sample(x=1:10,10,replace=FALSE),
                    y=sample(x=1:10,10,replace=FALSE))
plot2 <- data.frame(x=sample(x=1:10,10,replace=FALSE),
                    y=sample(x=1:10,10,replace=FALSE))
plot3 <- data.frame(x=sample(x=1:10,10,replace=FALSE),
                    y=sample(x=1:10,10,replace=FALSE))

layout(matrix(c(2,1,1,3,1,1),2,3,byrow=TRUE))
plot(plot1$x,plot1$y)
plot(plot2$x,plot2$y)
plot(plot3$x,plot3$y)

matrixlayout 命令可让您将多个图形排列成一个图形。基本上,您将每个图的数量(按照您将要调用的顺序)放入每个单元格中,然后无论安排如何,最终都会成为您的图的布局方式。例如,在上面的例子中,matrix(c(2,1,1,3,1,1),byrow=TRUE) 会生成一个如下所示的矩阵:

     [,1] [,2] [,3]
[1,]    2    1    1
[2,]    3    1    1

所以,你可以得到这样的结果:

编辑添加:

好的,所以,如果您想在角落整合一个绘图,您可以使用相同的layout 命令,只需更改矩阵即可。例如,这是不同的代码:

layout(matrix(c(1,1,2,1,1,1),2,3,byrow=TRUE))
plot1 <- data.frame(x=1:10,y=c(9,10,8,7,3,4,1,2,5,6))
plot2 <- data.frame(x=1:10,y=c(6,7,5,1,2,8,3,10,9,4))
plot(plot1$x,plot1$y,type="o",col="red")
plot(plot2$x,plot2$y,type="o",xlab="",ylab="",main="",sub="",col="blue")

得到的矩阵是:

     [,1] [,2] [,3]
[1,]    1    1    2
[2,]    1    1    1

出来的情节是这样的:

【讨论】:

  • @TAReham 谢谢,如果我想要一个小情节在另一个?
  • @TAReham 获取左上角和另一个地块内部的小块?
  • @TAReham 再次感谢您
【解决方案3】:

您也可以使用par(fig=..., new=TRUE)

x <- rnorm(100)
hist( x, col = "light blue" )
par( fig = c(.7, .95, .7, .95), mar=.1+c(0,0,0,0), new = TRUE )
qqnorm(x, axes=FALSE, xlab="", ylab="", main="")
qqline(x, col="blue", lwd=2)
box()

【讨论】:

  • 我非常喜欢这个选项,因为它简单且能够使用基本绘图功能。作为一个“网格”用户,我自己没有用,但我必须记住这一点以供其他人询问。感谢您指出这一点。
【解决方案4】:

TeachingDemos 包中的subplot 函数对基本图形完全执行此操作。

创建全尺寸图,然后使用您想要在子图中使用的绘图命令调用subplot,并指定子图的位置。位置可以通过“topleft”等关键字指定,也可以指定当前绘图用户坐标系中的坐标。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多