Search code examples
rplotgraphstatisticsinteraction

How to adjust legend position of interaction.plot and lineplot.CI?


I'm a beginner in coding. I was trying to create an interaction plot. Here's my code:

data is clinicaltrials from the data of the book "Learning Statistics with R."

library(sciplot)
library(lsr)
library(gplots)
lineplot.CI(x.factor = clin.trial$drug,
             response = clin.trial$mood.gain,
             group = clin.trial$therapy,
             ci.fun = ciMean,
             xlab = "Drug",
             ylab = "Mood Gain")

and it produces the graph like this: Interaction Plot 1

As can be seen in the graph, the legend box is not within my screen.

Also I tried creating another plot using the following code:

interaction.plot(x.factor = clin.trial$drug,
                 trace.factor = clin.trial$therapy,
                 response = clin.trial$mood.gain,
                 fun = mean,
                 type = "l",
                 lty = 1,  # line type
                 lwd = 2,  # line width
                 legend = T,
                 xlab = "Drug", ylab = "Mood Gain",
                 col = c("#00AFBB", "#E7B800"),
                 xpd = F,
                 trace.label = "Therapy")

For this code, I got the graph like this: Interaction plot 2

In this graph, the legend does not have labels.

Could anyone help me with these problems regarding legend?


Solution

  • You probably plan to save the plot via RStudio GUI. When you resize the plot window with your mouse, you need to run the code again to refresh the legend dimensions.

    However, it's advantageous to use a more sophisticated method, e.g. to save it as a png with fixed dimensions like so:

    library("sciplot")
    library("lsr")
    library("gplots")
    
    png("Plot_1.png", height=400, width=500)
    lineplot.CI(x.factor=clin.trial$drug,
                response=clin.trial$mood.gain,
                group=clin.trial$therapy,
                ci.fun=ciMean,
                xlab="Drug",
                ylab="Mood Gain"
    )
    dev.off()
    
    png("Plot_2.png", height=400, width=500)
    interaction.plot(x.factor=clin.trial$drug,
                     trace.factor=clin.trial$therapy,
                     response=clin.trial$mood.gain,
                     fun=mean,
                     type="l",
                     lty=1,  # line type
                     lwd=2,  # line width
                     legend=T,
                     xlab="Drug", ylab="Mood Gain",
                     col=c("#00AFBB", "#E7B800"),
                     xpd=F,
                     trace.label="Therapy")
    dev.off()
    

    enter image description here

    enter image description here

    The plots are saved into your working directory, check getwd() .

    Edit

    You could also adjust the legend position.

    In lineplot.CI you may use arguments; either by using characters just for x, e.g. x.leg="topleft" or both coordinates as numeric x.leg=.8, y.leg=2.2.

    interaction.plot does not provide yet this functionality. I provide a hacked version below. Arguments are called xleg and yleg, functionality as above.

    See ?legend for further explanations.

    interaction.plot <- function (x.factor, trace.factor, response, fun = mean,
                                  type = c("l", "p", "b", "o", "c"), legend = TRUE, 
                                  trace.label = deparse(substitute(trace.factor)), 
                                  fixed = FALSE, xlab = deparse(substitute(x.factor)),
                                  ylab = ylabel, ylim = range(cells, na.rm = TRUE), 
                                  lty = nc:1, col = 1, pch = c(1L:9, 0, letters), 
                                  xpd = NULL, leg.bg = par("bg"), leg.bty = "n", 
                                  xtick = FALSE, xaxt = par("xaxt"), axes = TRUE, 
                                  xleg=NULL, yleg=NULL, ...) {
      ylabel <- paste(deparse(substitute(fun)), "of ", deparse(substitute(response)))
      type <- match.arg(type)
      cells <- tapply(response, list(x.factor, trace.factor), fun)
      nr <- nrow(cells)
      nc <- ncol(cells)
      xvals <- 1L:nr
      if (is.ordered(x.factor)) {
        wn <- getOption("warn")
        options(warn = -1)
        xnm <- as.numeric(levels(x.factor))
        options(warn = wn)
        if (!anyNA(xnm)) 
          xvals <- xnm
      }
      xlabs <- rownames(cells)
      ylabs <- colnames(cells)
      nch <- max(sapply(ylabs, nchar, type = "width"))
      if (is.null(xlabs)) 
        xlabs <- as.character(xvals)
      if (is.null(ylabs)) 
        ylabs <- as.character(1L:nc)
      xlim <- range(xvals)
      if (is.null(xleg)) {
        xleg <- xlim[2L] + 0.05 * diff(xlim)
        xlim <- xlim + c(-0.2/nr, if (legend) 0.2 + 0.02 * nch else 0.2/nr) * 
          diff(xlim)
      }
      dev.hold()
      on.exit(dev.flush())
      matplot(xvals, cells, ..., type = type, xlim = xlim, ylim = ylim, 
              xlab = xlab, ylab = ylab, axes = axes, xaxt = "n", 
              col = col, lty = lty, pch = pch)
      if (axes && xaxt != "n") {
        axisInt <- function(x, main, sub, lwd, bg, log, asp, 
                            ...) axis(1, x, ...)
        mgp. <- par("mgp")
        if (!xtick) 
          mgp.[2L] <- 0
        axisInt(1, at = xvals, labels = xlabs, tick = xtick, 
                mgp = mgp., xaxt = xaxt, ...)
      }
      if (legend) {
        yrng <- diff(ylim)
        if (is.null(yleg))
          yleg <- ylim[2L] - 0.1 * yrng
        if (!is.null(xpd) || {
          xpd. <- par("xpd")
          !is.na(xpd.) && !xpd. && (xpd <- TRUE)
        }) {
          op <- par(xpd = xpd)
          on.exit(par(op), add = TRUE)
        }
        # text(xleg, ylim[2L] - 0.05 * yrng, paste("  ", 
        #                                          trace.label), adj = 0)
        if (!fixed) {
          ord <- sort.list(cells[nr, ], decreasing = TRUE)
          ylabs <- ylabs[ord]
          lty <- lty[1 + (ord - 1)%%length(lty)]
          col <- col[1 + (ord - 1)%%length(col)]
          pch <- pch[ord]
        }
        legend(xleg, yleg, legend = ylabs, col = col, 
               title = if (trace.label == "") NULL else trace.label,
               pch = if (type %in% c("p", "b")) 
                 pch, lty = if (type %in% c("l", "b")) 
                   lty, bty = leg.bty, bg = leg.bg)
      }
      invisible()
    }
    

    Data:

    lk <- "https://learningstatisticswithr.com/data.zip"
    tmp <- tempfile()
    tmp.dir <- tempdir()
    download.file(lk, tmp)
    unzip(tmp, exdir=tmp.dir)
    load("data/clinicaltrial.Rdata")