I'm trying to make a heatmap with pairwise-Fst values (statistic ranging from 0 to 1) in the lower left triangle and the associated p-value in the upper right triangle. I'd like the order along the axes to be: MSI, WB, JI, QC. I can make two heatmaps with geom_tile
in ggplot2
and Frankenstein them together (see picture below of what I'm looking for), but this is not a reproducible/good approach.
The dataframe I used to make the square heatmap is as follows (named pairwise_fst_maxmeanDP_df):
structure(list(Order = c(1, 11, 14, 16, 5, 2, 12, 15, 8, 6, 3,
13, 10, 9, 7, 4), Population = c("MSI", "MSI", "MSI", "MSI",
"WB", "WB", "WB", "WB", "JI", "JI", "JI", "JI", "QC", "QC", "QC",
"QC"), Comparison_Pop = c("MSI", "WB", "JI", "QC", "MSI", "WB",
"JI", "QC", "MSI", "WB", "JI", "QC", "MSI", "WB", "JI", "QC"),
COMBO = c(0, 0, 0, 0, 0.008, 0, 0.001, 0, 0.007, 0.001, 0,
0, 0.009, 0.003, 0.002, 0), F_ST = c(0, 0.008, 0.007, 0.009,
0.008, 0, 0.001, 0.003, 0.007, 0.001, 0, 0.002, 0.009, 0.003,
0.002, 0), P_Value = c(0, 0, 0, 0, 0, 0, 0.001, 0, 0, 0.001,
0, 0, 0, 0, 0, 0), F_ST_Lab = c("\"\"", "8.0000000000000002E-3",
"7.0000000000000001E-3", "8.9999999999999993E-3", "8.0000000000000002E-3",
"\"\"", "1E-3", "3.0000000000000001E-3", "7.0000000000000001E-3",
"1E-3", "\"\"", "2E-3", "8.9999999999999993E-3", "3.0000000000000001E-3",
"2E-3", "\"\""), P_Value_Lab = c("(<0.001)", "(<0.001)",
"(<0.001)", "(<0.001)", "(<0.001)", "(<0.001)", "(0.001)",
"(<0.001)", "(<0.001)", "(0.001)", "(<0.001)", "(<0.001)",
"(<0.001)", "(<0.001)", "(<0.001)", "(<0.001)")), class = c("tbl_df",
"tbl", "data.frame"), row.names = c(NA, -16L))
The dataframe I used to try and make the 'triangle' heatmap is as follows (named pairwise_fst_maxmeanDP_df_lowerTri):
structure(list(Population = structure(c(1L, 1L, 1L, 1L, 2L, 2L,
2L, 3L, 3L, 4L), levels = c("MSI", "WB", "JI", "QC"), class = "factor"),
Comparison_Pop = structure(c(1L, 2L, 3L, 4L, 2L, 3L, 4L,
3L, 4L, 4L), levels = c("MSI", "WB", "JI", "QC"), class = "factor"),
COMBO = c(0, 0, 0, 0, 0, 0.001, 0, 0, 0, 0), F_ST = c(0,
0.008, 0.007, 0.009, 0, 0.001, 0.003, 0, 0.002, 0), P_Value = c(0,
0, 0, 0, 0, 0.001, 0, 0, 0, 0), F_ST_Lab = c("\"\"", "8.0000000000000002E-3",
"7.0000000000000001E-3", "8.9999999999999993E-3", "\"\"",
"1E-3", "3.0000000000000001E-3", "\"\"", "2E-3", "\"\""),
P_Value_Lab = c("(<0.001)", "(<0.001)", "(<0.001)", "(<0.001)",
"(<0.001)", "(0.001)", "(<0.001)", "(<0.001)", "(<0.001)",
"(<0.001)"), Label = c("n/n", "0.008/(<0.001)", "0.007/(<0.001)",
"0.009/(<0.001)", "n/n", "0.001/(0.001)", "0.003/(<0.001)",
"n/n", "0.002/(<0.001)", "n/n"), Pair = c("1,1", "1,2", "1,3",
"1,4", "2,2", "2,3", "2,4", "3,3", "3,4", "4,4")), row.names = c(NA,
-10L), class = c("tbl_df", "tbl", "data.frame"))
The code I used to generate the first square heatmap (Fst) is as follows:
fst_maxmeanDP_rmRelated <- ggplot(pairwise_fst_maxmeanDP_df, aes(Population, Comparison_Pop)) +
geom_tile(aes(fill = F_ST), colour = "white") +
scale_fill_gradient(low = "white", high = "#7570b3", bquote(F[ST])) +
geom_text(aes(label=pairwise_fst_maxmeanDP_df$F_ST),colour="black") +
xlab("Population") + ylab("Population") + theme_bw()
I tried extracting the triangles and combining them into a new plot, but the logistics of lining those up was above my head.
I would also be happy having a single lower triangle, colored based on the Fst values, with the Fst value and p-value written on the cell. This is along the lines of the answer here: How to do a triangle heatmap in R using ggplot2, reshape2, and Hmisc?, but I couldn't get this to work with my data (the heatmap cells weren't all in the same triangle). I tried simpler code without the labels, but the graph wasn't lined up:
ggplot(pairwise_fst_maxmeanDP_df_lowerTri, aes(Population, Comparison_Pop)) +
theme_bw() +
xlab('Population') +
ylab('Population') +
geom_tile(aes(fill = F_ST), color='white') +
scale_fill_gradient(low = 'white', high = 'darkblue', space = 'Lab') +
theme(axis.text.x=element_text(angle=90),
axis.ticks=element_blank(),
axis.line=element_blank(),
panel.border=element_blank(),
panel.grid.major=element_line(color='#eeeeee'))
I've tried a lot of iterations of code and can't seem to find something that will suit my needs, and would sincerely appreciate any help!
Picture of desired output: