Shaxi Liver
Shaxi Liver

Reputation: 1120

Plotting row by row together with two fixed rows.

As the title says I would like to do some line plots. Let's use the mtcars as an example.

I would like to plot in total 10 rows from this data set. I chose those ones:

> dput(vec)
c("Mazda RX4", "Mazda RX4 Wag", "Datsun 710", "Hornet 4 Drive", 
"Hornet Sportabout", "Valiant", "Duster 360", "Merc 240D", "Merc 230", 
"Merc 280")

So first of all I decided to subset the whole data set:

tbl_mtcars <- mtcars[row.names(mtcars) %in% vec, ]

and than I would like to plot those rows but with the assumption that on each plot there will be only 3 lines. The lines for Merc 230 and Merc 280 should always be on the plot and the rest should be added one by one.

Would be great if that could be done with ggplot:

The function below is just the example of code which I often use for plotting.

ggplot(tbl_mtcars, aes(gear, carb, group=factor(Name))) +
  theme(legend.title=element_blank()) +
  geom_line(aes(color=factor(Name))) +
  ggtitle("Title")+
  theme(axis.text.x = element_text(angle = 90, hjust = 1))

Upvotes: 0

Views: 106

Answers (2)

zyurnaidi
zyurnaidi

Reputation: 2263

First of all, mtcars might not be the best dataset to illustrate your need. Instead, I created a data frame of 10 rows and 5 columns (representing observations).

The thing is, ggplot needs a specific form of data ('long' instead of 'wide'), so before we can draw a graph, we need to modify the data first. Here I use melt from reshape2 package.

Now we can generate the plots while keeping in mind the two fix rows (IDs) you mentioned. Here, the last two IDs are fixed. Please note that I only present the vanilla-type of plots here, without much cosmetics.

(EDIT/UPDATE: as per @Paul Hiemstra's suggestion, replacing for loop with lapply and removing eval-parse combination, although still keeping the grid.arrange method)

# Generate data: 10 IDs each with 5 observations
df <- data.frame(matrix(rnorm(50), 10, 5))
df$id <- as.numeric(rownames(df))

# Melt the data
require(reshape2)
df2 <- melt(df, id.vars = "id")

# Generate plots
require(ggplot2)
plot.list <- lapply(1:(max(df2$id)-2), function(i) {
  df2.i <- df2[df2$id %in% c(i, 9, 10), ]
  ggplot(df2.i) +
    geom_line(aes(x = as.numeric(variable), y = value, colour = factor(id)))
})

# Combine plots
require(gridExtra)
do.call(grid.arrange, plot.list)

output: eight graphs

Upvotes: 4

Paul Hiemstra
Paul Hiemstra

Reputation: 60924

After some data manipulation you can use the same dataset as @zyurnaidi, but using facetting and not grid.arrange. The trick is to use two geom_line's and facet_wrap. The first geom_line draws the lines you always want to see, the second the varying line.

library(dplyr)
library(tidyr)
df2 = as.data.frame(t(df)) %>% 
  gather(variable_id, value, -V9, -V10) %>% 
  gather(always_show_id, value_always, V9, V10) %>% 
  group_by(variable_id, always_show_id) %>% mutate(x_id = seq_len(length(variable_id)))
head(df2)
  variable_id       value always_show_id value_always x_id
1          V1 -0.89596500             V9   -0.1758441    1
2          V1  0.42307486             V9   -0.2183904    2
3          V1 -1.13538973             V9    0.3609882    3
4          V1 -0.05927355             V9   -0.3902112    4
5          V1 -0.69209362             V9    0.1045214    5
6          V2 -0.56098448             V9   -0.1758441    1

df2 %>% ggplot() + 
  geom_line(aes(x = x_id, y = value_always, group = always_show_id)) + 
  geom_line(aes(x = x_id, y = value), color = 'red') + 
  facet_wrap(~ variable_id)

enter image description here

Upvotes: 3

Related Questions