Use facet_grid to render the pair value (Heatmap) in ggplot2

I have data containing pairwise numerical data for 10 samples:

data = dget(url("https://git.io/vCTpG")) 

The data is as follows:

 sampleB sampleA ol labelA labelB facetA facetB 2409 2409 100 2409|B 2409|BBB 2409 2413 0 2413|A 2409|BAB 2409 2414 0 2414|A 2409|BAB 2409 2417 0 2417|C 2409|BCB 2409 2411 0 2411|A 2409|BAB 2409 2418 0 2418|B 2409|BBB 2409 2416 0 2416|C 2409|BCB 2409 2412 4 2412|B 2409|BBB 2409 2415 0 2415|C 2409|BCB 2409 2410 19 2410|A 2409|BAB ... ... ... ... ... ... ... 

I want to visualize ol values ​​in a heatmap:

 library(ggplot2) ggplot(data = data, mapping = aes(x=labelA, y=labelB)) + geom_tile(mapping = aes(fill=ol)) + scale_fill_gradient(low = "white", high = "black") + theme(legend.position = "none") + theme(axis.text.x = element_text(angle = 90, hjust = 1)) 

plot without edge

Now I would like to structure the 10 by 10 heat map by the category to which each sample belongs, namely A,B or C in this example. However, if I use facet_grid ...

 last_plot() + facet_grid(facetA~facetB) 

plot with facet

... this leads to 30-30, and not 10 10 heatmaps, which are divided into 3 categories (although so far only 100 values ​​are displayed). I remember that fixed it with

 last_plot() + facet_grid(facetA~facetB, scales = "free", space = "free") 

in the past, however, I can no longer reproduce this. The desired solution would look like this (it was gimped, not ggplot):

enter image description here

those. reordered, grouped matrix 10 by 10.

+5
source share
1 answer

You need to use facet_wrap() instead of facet_grid() or change the order of the faces in facet_grid() , as suggested in the comments.

The reason is that by definition facet_grid does not allow y-axis borders to be different in panels on the same line. In other words, all three panels in the top row must have the same y limits, all three panels in the second row must have the same y limits, etc. Adding scales = "free_y" means that the first row is allowed to have different y limits from the second row (but within this row all panels should always have the same y limits). In your example, when you use

 facet_grid(facetA ~ facetB, scales = "free") 

you force ggplot use all y values ​​for all lines; for example, the left pane in the top row should contain the value 2418|B , because this value is present in the middle pane of the top row. Facies order reversal occurs to do the job in this case due to the structure of your data. (I just give an example for the y axis, but the same is true for the limits of the x axis when using scales = "free_x" .)

If you want to have different x and y scales for each panel, regardless of those closest to it, you will need to use facet_wrap .

Edit A more detailed explanation of how to get the desired shape. Returning to your specific example, reversing your faces will give

 p <- ggplot(data = data, mapping = aes(x=labelA, y=labelB)) + geom_tile(mapping = aes(fill=ol)) + scale_fill_gradient(low = "white", high = "black") + theme(legend.position = "none") + theme(axis.text.x = element_text(angle = 90, hjust = 1)) + facet_grid(facetB ~ facetA, scales = "free") p 

enter image description here

This contains all the panels you want. To get the order you are requesting is just a matter of row swapping. This can be done by setting the order of facetB levels (edit: or, as @ user20650 suggested in the comments, setting as.table=FALSE in facet_grid() ):

 data1 <- data data1$facetB <- factor(data1$facetB, levels = c("C", "B", "A")) p %+% data1 

enter image description here

+2
source

Source: https://habr.com/ru/post/1233347/


All Articles