Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Remove blank lines from geom_tile

Tags:

r

ggplot2

I have a data frame with 5 columns:

N1 <- an integer between c(125,100,80,70,60,50,40,30,20)

N2 <- an integer between c(1,5,10,15,20,25,30,35,40,50,60,80,100)

Type <- Two different types

Rang <- a number

crit <- a character, only one value

N1 is always greater than N2. Here is an example of the beginning of my data frame (Rang_final):

N1  N2     Type      rang     crit
125   1 SST-T_2m  41.86395 BE_proba
125   1 T_2m-SST 163.41217 BE_proba
100   1 SST-T_2m  32.88181 BE_proba
100   1 T_2m-SST 137.44479 BE_proba
 80   1 SST-T_2m  22.57176 BE_proba
 80   1 T_2m-SST 112.52334 BE_proba
 70   1 SST-T_2m  21.30066 BE_proba
 70   1 T_2m-SST  99.65523 BE_proba
 60   1 SST-T_2m  18.48731 BE_proba
 60   1 T_2m-SST  85.36945 BE_proba
 50   1 SST-T_2m  18.60074 BE_proba
 50   1 T_2m-SST  71.58960 BE_proba
 40   1 SST-T_2m  18.58180 BE_proba
 40   1 T_2m-SST  62.82670 BE_proba
 30   1 SST-T_2m  20.53982 BE_proba
 30   1 T_2m-SST  48.58923 BE_proba
 20   1 SST-T_2m  27.15737 BE_proba
 20   1 T_2m-SST  36.04175 BE_proba
125   5 SST-T_2m 101.82300 BE_proba
125   5 T_2m-SST 168.69954 BE_proba
100   5 SST-T_2m  91.10644 BE_proba
...

I want to have all these information in only one graph so I am looking for using ggplot and geom_tile like this:

p <- ggplot(Rang_final)
p <- (p
      + geom_tile(data=Rang_final[Rang_final$Type=="SST-T_2m",], aes(x=N1, y=N2, fill=rang))
      + geom_tile(data=Rang_final[Rang_final$Type=="T_2m-SST",], aes(x=N2, y=N1, fill=rang))
      + scale_fill_gradient2(name="Rang", low="deepskyblue",mid="yellow",high="red", midpoint=100, na.value = "grey50")
      + theme(axis.title.x = element_text(size=14, face="bold"),
          axis.title.y = element_text(size=14, face="bold"),
          strip.text.x = element_text(size=14, face="bold"),
          strip.text.y = element_text(size=14, face="bold"),
          axis.text=element_text(size=14),
          axis.title.y=element_text(size=14, face="bold"),
          legend.key=element_rect(size=0.5, colour="black"),
          legend.text=element_text(size=10),
          legend.margin=unit(0,"lines"),
          legend.key.size=unit(0.8,"cm"),
          legend.text.align=0)
  + theme_bw()

)

print(p)

And this is what I get (the class of N1 and N2 is numeric): R

But I want to remove the blank lines so I tried to transform N1 and N2 as factors:

Rang_final$N1 <- factor(Rang_final$N1, levels = c("20", "30", "40", "50", "60", "70", "80", "100", "125") ,ordered = TRUE)
Rang_final$N2 <- factor(Rang_final$N2, levels = c("1", "5", "10", "15", "20", "25", "30", "35", "40", "50", "60", "80", "100", "125") ,ordered = TRUE)

R

But here my numbers are not in the increasing order.

Here, I was also using N1 and N2 as factors but I can't manage to have the two different types on the same graph with this scale:

p <- ggplot(Rang_final, aes(x=N1, y=N2))
p <- (p
      + geom_tile(aes(fill=rang))
      + facet_grid(Type ~ crit, scales="free") 
      + scale_fill_gradient2(name="Rang", low="deepskyblue",mid="yellow",high="red", midpoint=100, na.value = "grey50")
      + theme(axis.title.x = element_text(size=14, face="bold"),
          axis.title.y = element_text(size=14, face="bold"),
          strip.text.x = element_text(size=14, face="bold"),
          strip.text.y = element_text(size=14, face="bold"),
          axis.text=element_text(size=14),
          axis.title.y=element_text(size=14, face="bold"),
          legend.key=element_rect(size=0.5, colour="black"),
          legend.text=element_text(size=10),
          legend.margin=unit(0,"lines"),
          legend.key.size=unit(0.8,"cm"),
          legend.text.align=0)
      + theme_bw()

)

R

Can someone help me?

like image 897
Chika Avatar asked Sep 01 '14 10:09

Chika


1 Answers

Here is my suggestion. The reason why your x-axis and y-axis numbers are not in order, when you convert N1 and N2 to factor, is that you are not assigning the order you want. Here I used the overflow package, so your data frame is called mydf, which is identical to what you posted. I think there are two things you need to do.

1) Reordering factor

What you need is to reorder your factors in a right way. When you converted characters to factors in your script, something like this happened.

#> mydf$N1 <- as.factor(mydf$N1)
#> levels(mydf$N1)
#[1] "20"  "30"  "40"  "50"  "60"  "70"  "80"  "100" "125"
#> unclass(mydf$N1)
#[1] 9 9 8 8 7 7 6 6 5 5 4 4 3 3 2 2 1 1 9 9
#attr(,"levels")
#[1] "20"  "30"  "40"  "50"  "60"  "70"  "80"  "100" "125"

If you look at unclass(), you see that "20" has 9. You want "20" to have 1 in unclass(). For this reason, you want to sort your data frame. This caused the weird number order. Before you convert character to factor, you want to sort N1 and N2, and convert them to factor.

library(dplyr)
# Sort mydf by N1
mydf <- arrange(mydf, N1)

# Convert N1 to factor
mydf$N1 <- as.factor(mydf$N1)

Here you see that "20" has 1 in unclass and "125" has 9. So this is the order you want.

#> levels(mydf$N1)
#[1] "20"  "30"  "40"  "50"  "60"  "70"  "80"  "100" "125"
#> unclass(mydf$N1)
#[1] 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 9 9
#attr(,"levels")
#[1] "20"  "30"  "40"  "50"  "60"  "70"  "80"  "100" "125"

2) Data subsetting

This may/may not be necessary. But, so far I think this is necessary. The following seems not to be good.

  + geom_tile(data=Rang_final[Rang_final$Type=="SST-T_2m",], aes(x=N1, y=N2, fill=rang))
  + geom_tile(data=Rang_final[Rang_final$Type=="T_2m-SST",], aes(x=N2, y=N1, fill=rang))

So, I did a trick to arrange your data.

 # Subset data using dplyr
 america <- filter(mydf, Type == "SST-T_2m")
 brazil <- filter(mydf, Type == "T_2m-SST")

 # Reverse N1 and N2 in brazil (So N1 is actually N2, and N2 is actually N1)
 colnames(brazil) <- c("N2","N1", "Type", "rang", "crit")
 brazil[,c(2,1,3:5)]

After subsetting the original data and did the trick to the brazil data frame, I combined them. Then, I arrange factor order as I mentioned earlier.

 canada <- rbind(america, brazil)
 canada <- arrange(canada,N1)
 canada$N1 <- as.factor(canada$N1)

 canada <- arrange(canada,N2)
 canada$N2 <- as.factor(canada$N2)

Now I draw a figure. I somehow have issues with legend related things. So I removed them here.

x <- ggplot(canada)
x <- (x
  + geom_tile(aes(x=N1, y=N2, fill =rang))
  + scale_fill_gradient2(name="Rang", low="deepskyblue",mid="yellow",high="red",     midpoint=100, na.value = "grey50")
  + theme(axis.title.x = element_text(size=14, face="bold"),
      axis.title.y = element_text(size=14, face="bold"),
      strip.text.x = element_text(size=14, face="bold"),
      strip.text.y = element_text(size=14, face="bold"),
      axis.text=element_text(size=14),
      axis.title.y=element_text(size=14, face="bold"))
  + theme_bw()

 )

Let me know if this works for you.

enter image description here

like image 192
jazzurro Avatar answered Oct 18 '22 23:10

jazzurro