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):
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)
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()
)
Can someone help me?
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With