Search code examples
rggplot2plotfigure

Multiple plots in one figure in R


I have three plots and I want to show them in a figure like below

link enter image description here

I made a few attempts but I was not successful. My codes are given below:

dat <- read.table(text="
dates   PS.230  PS.286  PS.389
3.01.2018   20.75103    16.69312    -6.503637
15.01.2018  15.00284    16.03211    16.1058
8.02.2018   11.0789 7.438522    -2.970704
20.02.2018  15.10865    12.8969 3.935687
4.03.2018   24.74799    19.25148    9.186779
28.03.2018  -1.299456   7.028817    -8.126284
9.04.2018   4.778902    8.309322    -3.450085
21.04.2018  7.131915    9.484932    -4.326919


", header=T, stringsAsFactors=FALSE)
dat$dates <- as.Date(dat$dates, "%d.%m.%Y")


library(ggplot2)
library(tidyverse)

a <- ggplot(dat, aes(x=dates, y=PS.230)) +
  geom_point() +
  geom_line() +
  geom_smooth(se = FALSE, method = lm, size = 0.15, color = "#da0018") +  #cizgi eklemek icin
  scale_x_date(date_breaks = "1 months",date_labels = "%Y-%m",
               limits = as.Date.character(c("01/12/2017","31/12/2018"),
                                          format = "%d/%m/%Y")) +
  ylim(-20,40) +
  ylab("[mm/year]") +
  xlab("") +
  theme_linedraw() #theme_light
a + theme(
  axis.text.x = element_text(angle = 45, hjust = 1),
  panel.grid.major.x = element_blank(),
  panel.grid.minor.x = element_blank()
)

b <- ggplot(dat, aes(x=dates, y=PS.286)) +
  geom_point() +
  geom_line() +
  geom_smooth(se = FALSE, method = lm, size = 0.15, color = "#da0018") +  #cizgi eklemek icin
  scale_x_date(date_breaks = "1 months",date_labels = "%Y-%m",
               limits = as.Date.character(c("01/12/2017","31/12/2018"),
                                          format = "%d/%m/%Y")) +
  ylim(-20,40) +
  ylab("[mm/year]") +
  xlab("") +
  theme_linedraw() #theme_light
b + theme(
  axis.text.x = element_text(angle = 45, hjust = 1),
  panel.grid.major.x = element_blank(),
  panel.grid.minor.x = element_blank()
)

c <- ggplot(dat, aes(x=dates, y=PS.389)) +
  geom_point() +
  geom_line() +
  geom_smooth(se = FALSE, method = lm, size = 0.15, color = "#da0018") +  #cizgi eklemek icin
  scale_x_date(date_breaks = "1 months",date_labels = "%Y-%m",
               limits = as.Date.character(c("01/12/2017","31/12/2018"),
                                          format = "%d/%m/%Y")) +
  ylim(-20,40) +
  ylab("[mm/year]") +
  xlab("") +
  theme_linedraw() #theme_light
c + theme(
  axis.text.x = element_text(angle = 45, hjust = 1),
  panel.grid.major.x = element_blank(),
  panel.grid.minor.x = element_blank()
)

in the link I provided, much better graphics were drawn with fewer lines. my codes seem a little more complicated and frankly i couldn't get out. a, b and c plots in one image and only one date axes. How can I modify the codes to achieve sample result? Thank you.


Solution

  • Thank you for posting your data. As mentioned, the first step is to arrange your dataset so that it is in Tidy Data format. The information in dat$PS.230, dat$PS.286 and dat$PS.389 should be better represented in two columns:

    1. First Column: name of data type - We'll call this column dat$value_type and it will have values that indicate if dat$results comes from PS.230, PS.286, or PS.389.

    2. Second Column: value of data - We'll call this column dat$result and it just shows the value. This will be the y= aesthetic for all plots.

    Pre-Processing: Gather into TidyData format

    Use the gather() function to gather all columns in to a key ("value_type") and a "value" ("result"). We'll gather all columns except for "dates", so we just note to exclude that column via -dates:

    dat <- dat %>% gather(key='value_type', value='result', -dates)
    

    Plot

    For the plot, you apply x and y aesthetics to "date" and "result". You can use "value_type" to differentiate based on color and create your legend for points and lines. You also use "value_type" as the column for creating the facets (the three separate plots) via use of facet_grid() function. Note that value_type ~ . arranges by "value_type" vertically, whereas . ~ value_type would arrange horizontally:

    ggplot(dat, aes(x=dates, y=result)) +
      geom_line(aes(color=value_type)) +
      geom_point(aes(color=value_type)) +
      scale_x_date(date_breaks = '1 months', date_labels = '%Y-%m') +
      facet_grid(value_type ~ .) +
      theme_bw()
    

    enter image description here