0

I have a modelling program prepared which produces 26 separate files that I need to contour plot in the same way in R - I am planning on running this program repeatedly, and hence have been trying to create a loop which creates and saves plots for all 26 files for each run.

I'm trying to save the files with their original file names (have put a placehold name in for now) hence why I have created the object 'names' and save each to a png or jpeg file. At the moment the loop is only saving 1 file (despite reading in 4 sets of data with list.files) and this is appearing as a white square with the correct dimensions rather than the graph produced by 'makeplot' (have tested on individual files).

Sample of my data:

Z    X     T
0    0     0
0    0.005 0
0    0.01  0
0    0.015 0

(and so on for 84k rows)

My code:

filenames <- list.files(path=".",
                    pattern="csv", 
                    full.names=TRUE)

names <- as.vector(filenames)

# Creating a directory to save contour plots
dir.create("Contour plots")

#Creates a contour plot in ggplot of the variable in xz space
makeplot <- function(filename) {
  data <- as.data.frame(read.csv(file = filename), header = FALSE)
  ggplot(data=data, mapping = aes(x = data[,2], 
                              y=data[,1], 
                              z = data[,3])) +

    geom_raster(data=data, aes(fill=data[,3]), show.legend=TRUE, interpolate         
    = FALSE) +
    scale_fill_gradient(limits=range(data[,3]), high = 'red', low =     
    'white')+
    geom_contour(bins = 30, colour = "black") +
    xlab(label = "Distance from ridge axis") +
    ylab(label = "Depth") +
    theme_classic()+
    coord_cartesian(
    ylim = c(0,1), xlim = c(0,2))+
    scale_x_continuous(expand = c(0, 0)) + 
    scale_y_continuous(expand = c(0, 0)) +
    guides(fill=guide_legend(title="Yb concentration")) +
    theme(legend.position="bottom")
  }

for (f in filenames) {
  png(filename="Rplot%03d.png", height = 600, width = 1200)
  makeplot(f)
  dev.off()
}

Any help would be appreciated!

lmm
  • 33
  • 1
  • 5
  • I think you just need to put the `png(..)` and `dev.off()` *outside* of your `for` loop and you're there. – Milan Valášek Nov 15 '18 at 16:26
  • Hi Milan, thanks for getting back to me - this still doesn't seem to be working, I can only assume it is something wrong with my syntax in the for-loop? – lmm Nov 15 '18 at 16:39
  • 2
    Hi, try `print(makeplot(f))` in the loop? – Milan Valášek Nov 15 '18 at 16:46
  • Here is an old answer of mine that is very similar to what you are trying to do, and is fully reproducible. https://stackoverflow.com/questions/26034177/r-saving-multiple-ggplots-using-a-for-loop/26078489#26078489 – bdemarest Nov 15 '18 at 19:46
  • Thanks! I got it working in the end using print and also changing my call for the loop: 'pdf(file=pdfmaster[1], height=6, width=12) for (f in 1:length(filenames)) { print(makeplot(filenames[f])) } dev.off()' – lmm Nov 16 '18 at 12:34

1 Answers1

0

I would like to offer an alternative strategy

  1. input filepath

    filepath <- dir(path=".", pattern="csv", full.names=TRUE)

  2. edit your filenames with regex. e.g., replacing the ".csv" extension and/or get fancy with string literals and interpolation (see library(glue)). Most of the times in real life I do not want to carry forward the whole path generated by the full.names option above.

OUTPATH <- "whatever/Rplot"

filenames <- paste0(OUTPATH, gsub("\\.csv$", ".png", filepath))

edit your makeplot() signature like the following:

makeplot <- function(filepath, filenames) {

And move to a more idiomatic Map() to iterate over two lists NB: feel free to check out map2 from purrr as an alternative to Map()

Map(function(x, y) makeplot(filepath = x, filenames = y), 
     x = filepath, 
     y = filenames)
Pasqui
  • 591
  • 4
  • 12