গ্রিড.আরঞ্জ ব্যবহার করে আমি কীভাবে জিবিপ্লটগুলির একটি স্বেচ্ছাসেবী ব্যবস্থা করতে পারি?


93

এটি ggplot2 গুগল গ্রুপে ক্রস পোস্ট করা হয়েছে

আমার পরিস্থিতি হ'ল আমি এমন একটি ফাংশনে কাজ করছি যা একটি নির্বিচার সংখ্যক প্লটের আউটপুট দেয় (ব্যবহারকারীর সরবরাহ করা ইনপুট ডেটার উপর নির্ভর করে)। ফাংশনটি এন প্লটের একটি তালিকা দেয় এবং আমি এই প্লটগুলি 2 x 2 গঠনে রেখে দিতে চাই। আমি যুগপত সমস্যাগুলির সাথে লড়াই করছি:

  1. আমি কীভাবে নমনীয়তাটিকে স্বেচ্ছাসেবী (এন) সংখ্যক প্লট হস্তান্তর করতে পারি?
  2. আমি কীভাবে উল্লেখ করতে পারি যে আমি তাদের 2 x 2 রেখে দিতে চাই

আমার বর্তমান কৌশল প্যাকেজ grid.arrangeথেকে ব্যবহার করে gridExtra। এটি সম্ভবত অনুকূল নয়, বিশেষত যেহেতু, এবং এটি কী, এটি সম্পূর্ণরূপে কাজ করে না । এখানে তিনটি প্লটের পরীক্ষা-নিরীক্ষা করে আমার মন্তব্য করা নমুনা কোড:

library(ggplot2)
library(gridExtra)

x <- qplot(mpg, disp, data = mtcars)
y <- qplot(hp, wt, data = mtcars)
z <- qplot(qsec, wt, data = mtcars)

# A normal, plain-jane call to grid.arrange is fine for displaying all my plots
grid.arrange(x, y, z)

# But, for my purposes, I need a 2 x 2 layout. So the command below works acceptably.
grid.arrange(x, y, z, nrow = 2, ncol = 2)

# The problem is that the function I'm developing outputs a LIST of an arbitrary
# number plots, and I'd like to be able to plot every plot in the list on a 2 x 2
# laid-out page. I can at least plot a list of plots by constructing a do.call()
# expression, below. (Note: it totally even surprises me that this do.call expression
# DOES work. I'm astounded.)
plot.list <- list(x, y, z)
do.call(grid.arrange, plot.list)

# But now I need 2 x 2 pages. No problem, right? Since do.call() is taking a list of
# arguments, I'll just add my grid.layout arguments to the list. Since grid.arrange is
# supposed to pass layout arguments along to grid.layout anyway, this should work.
args.list <- c(plot.list, "nrow = 2", "ncol = 2")

# Except that the line below is going to fail, producing an "input must be grobs!"
# error
do.call(grid.arrange, args.list)

আমি যেমন করতে চাই না, আমি বিনীতভাবে কোণে আছড়ে পড়ি, অধীর আগ্রহে আমার চেয়ে অনেক বেশি বুদ্ধিমান একটি সম্প্রদায়ের সাড়া জাগানো প্রতিক্রিয়ার জন্য অপেক্ষা করি Especially


4
একটি খুব ভাল প্রশ্নে কুডোস। আমি কীভাবে একটি ভাল এসও [r] প্রশ্ন লিখতে পারি তার একটি উদাহরণ হিসাবে এটি ব্যবহার করতে যাচ্ছি।
জেডি লং

4
বিশেষত "বিনীতভাবে হুডলিং" অংশ - ভাল
খাঁজর

@ জেডি এবং @ বেন - আমি চাটুকার, ছেলেরা। আন্তরিকভাবে। এবং আমি সত্যিই সাহায্যের প্রশংসা করি।
17'50 এ ব্রিডেন্ডক

উত্তর:


45

আপনি বেশিরভাগ ওখানেই থাকেন! সমস্যাটি হ'ল do.callআশা করা যায় যে আপনার আরগগুলি একটি নামকৃত listঅবজেক্টে থাকবে। আপনি এগুলি তালিকায় রেখেছেন, তবে অক্ষরের স্ট্রিং হিসাবে, তালিকাভুক্ত আইটেম নেই।

আমি এই কাজ করা উচিত:

args.list <- c(plot.list, 2,2)
names(args.list) <- c("x", "y", "z", "nrow", "ncol")

বেন এবং জোশুয়া মন্তব্যগুলিতে যেমন উল্লেখ করেছেন, তালিকাটি তৈরি করার সময় আমি নামগুলি নির্ধারণ করতে পারতাম:

args.list <- c(plot.list,list(nrow=2,ncol=2))

বা

args.list <- list(x=x, y=y, z=x, nrow=2, ncol=2)

4
আমি কয়েকবার কোড পরিবর্তন করেছি। সম্পাদনার জন্য দুঃখিত। এটা কি এখন বুঝতে পারি? আমি যখন বলেছিলাম যে তারা আগে ভেক্টর ছিল, আমি ভুল বানান করি। এর জন্যে দুঃখিত.
জেডি লং

4
তালিকা তৈরির সময় আপনি অর্গগুলির নাম রাখতে পারেন:args.list <- list(x=x, y=y, z=x, nrow=2, ncol=2)
জোশুয়া উলরিচ

4
বেপারটা এমন না. আপনার সঠিক দৈর্ঘ্যের হয়। আপনার তালিকার কাঠামো জেডি তালিকার কাঠামোর চেয়ে আলাদা different Str () এবং নামগুলি () ব্যবহার করুন। আপনার সমস্ত তালিকার উপাদানগুলি নামবিহীন, সুতরাং do.callসফল হওয়ার জন্য, সেখানে অবশ্যই সঠিক অবস্থানের মিল থাকতে হবে।
আইআরটিএফএম

4
@ জেডি লং; আমি আন্তরিকভাবে একমত। এবং যদি এটি সমস্ত ত্রুটি প্রতিরোধ না করে তবে ভেন্য করুন, আপনি traceback()যদি নামযুক্ত যুক্তি ব্যবহার করেন তবে আপনি আরও অনেক ভাল ত্রুটি বার্তা এবং তথ্য পাবেন।
আইআরটিএফএম

4
আমি এখানে আলোচনাটি পুরোপুরি অনুসরণ করি না; প্রথম আর্গুমেন্ট যেহেতু grid.arrange()হয় ...অবস্থানগত ম্যাচিং সম্ভবত অপ্রাসঙ্গিক। প্রতিটি ইনপুট অবশ্যই গ্রিড অবজেক্ট (নাম সহ বা ছাড়াই), একটি নামযুক্ত প্যারামিটার grid.layoutবা বাকী যুক্তিগুলির জন্য একটি নামযুক্ত প্যারামিটার হতে হবে।
baptiste

16

এটা চেষ্টা কর,

require(ggplot2)
require(gridExtra)
plots <- lapply(1:11, function(.x) qplot(1:10,rnorm(10), main=paste("plot",.x)))

params <- list(nrow=2, ncol=2)

n <- with(params, nrow*ncol)
## add one page if division is not complete
pages <- length(plots) %/% n + as.logical(length(plots) %% n)

groups <- split(seq_along(plots), 
  gl(pages, n, length(plots)))

pl <-
  lapply(names(groups), function(g)
         {
           do.call(arrangeGrob, c(plots[groups[[g]]], params, 
                                  list(main=paste("page", g, "of", pages))))
         })

class(pl) <- c("arrangelist", "ggplot", class(pl))
print.arrangelist = function(x, ...) lapply(x, function(.x) {
  if(dev.interactive()) dev.new() else grid.newpage()
   grid.draw(.x)
   }, ...)

## interactive use; open new devices
pl

## non-interactive use, multipage pdf
ggsave("multipage.pdf", pl)

4
সংস্করণ> = gridExtra এর 0.9 marrangeGrob সব স্বয়ংক্রিয়ভাবে এই কাজ যখনই nrow * ncol <দৈর্ঘ্য (প্লট) প্রদান করে
Baptiste

5
ggsave("multipage.pdf", do.call(marrangeGrob, c(plots, list(nrow=2, ncol=2))))
baptiste

4

আমি কিছুটা দেরি করে উত্তর দিচ্ছি, তবে আর গ্রাফিক্স কুকবুকের এমন একটি সমাধান নিয়ে গিয়েছি যা বলা একটি কাস্টম ফাংশন ব্যবহার করে খুব অনুরূপ কিছু করে multiplot। সম্ভবত এটি অন্যদের যারা এই প্রশ্নটি খুঁজে পেতে সহায়তা করবে। আমি উত্তরটি যুক্ত করছি কারণ এই প্রশ্নের উত্তরগুলির উত্তরগুলির চেয়ে সমাধান আরও নতুন হতে পারে।

এক পৃষ্ঠায় একাধিক গ্রাফ (ggplot2)

এখানে বর্তমান ফাংশনটি রয়েছে, তবে দয়া করে উপরের লিঙ্কটি ব্যবহার করুন, কারণ লেখক উল্লেখ করেছেন যে এটি ggplot2 0.9.3-র জন্য আপডেট করা হয়েছে, যা ইঙ্গিত করে যে এটি আবার পরিবর্তন হতে পারে।

# Multiple plot function
#
# ggplot objects can be passed in ..., or to plotlist (as a list of ggplot objects)
# - cols:   Number of columns in layout
# - layout: A matrix specifying the layout. If present, 'cols' is ignored.
#
# If the layout is something like matrix(c(1,2,3,3), nrow=2, byrow=TRUE),
# then plot 1 will go in the upper left, 2 will go in the upper right, and
# 3 will go all the way across the bottom.
#
multiplot <- function(..., plotlist=NULL, file, cols=1, layout=NULL) {
  require(grid)

  # Make a list from the ... arguments and plotlist
  plots <- c(list(...), plotlist)

  numPlots = length(plots)

  # If layout is NULL, then use 'cols' to determine layout
  if (is.null(layout)) {
    # Make the panel
    # ncol: Number of columns of plots
    # nrow: Number of rows needed, calculated from # of cols
    layout <- matrix(seq(1, cols * ceiling(numPlots/cols)),
                    ncol = cols, nrow = ceiling(numPlots/cols))
  }

 if (numPlots==1) {
    print(plots[[1]])

  } else {
    # Set up the page
    grid.newpage()
    pushViewport(viewport(layout = grid.layout(nrow(layout), ncol(layout))))

    # Make each plot, in the correct location
    for (i in 1:numPlots) {
      # Get the i,j matrix positions of the regions that contain this subplot
      matchidx <- as.data.frame(which(layout == i, arr.ind = TRUE))

      print(plots[[i]], vp = viewport(layout.pos.row = matchidx$row,
                                      layout.pos.col = matchidx$col))
    }
  }
}

এক প্লট অবজেক্ট তৈরি করে:

p1 <- ggplot(...)
p2 <- ggplot(...)
# etc.

এবং তারপরে এগুলিকে পাস করে multiplot:

multiplot(p1, p2, ..., cols = n)
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.