First, you need to format your data frame from wide format to long format. The following is an example using tidyverse to format the data frame.
library(tidyverse)
dt2 <- dt %>%
rownames_to_column() %>%
gather(colname, value, -rowname)
head(dt2)
# rowname colname value
# 1 tension tension NA
# 2 cluster tension 1.943113e+08
# 3 migraineNoAura tension 8.462798e+00
# 4 migraineAura tension 2.833333e+00
# 5 tension cluster 1.500000e+00
# 6 cluster cluster NA
Now we are ready to use the ggplot2 to plot the heatmap using geom_tile.
ggplot(dt2, aes(x = rowname, y = colname, fill = value)) +
geom_tile()

How to make a “heatmap” from a data frame where two columns represent the x and y axis coordinates and a third represents the value to be mapped to the color?
R: Use dataframe for heatmap - Stack Overflow
dataframe - How to create a heatmap in R with data frames - Stack Overflow
making matrix from dataframe to make heatmap in R - Stack Overflow
I have been really struggling with how to do this. I’ve tried the following functions, but haven’t had success for the following reasons:
Heatmap - uses the index numbers and column names as opposed to the values in certain columns
Hexbin/2D histogram - my problem has nothing to to with frequency or “binning”, all the values are explicitly associated with a set of coordinates
Imshow - I can generate an image similar to what I want if I put the value column in a 2D array, but then when I graph, the axis values are based on the indices of the array and I lose all association between the values and the actual original coordinates
My friend showed me how to do it in R using ggplot/geom_tile, but I haven’t been able to find anything similar in Python
You may do either of these 2
df <- read.table(header = T, text = "protein value treatment
EPN1 0.986 treat1
LAMB1 0.881 treat2
PKP4 0.827 treat2
PKP2 0.739 treat3
BAIAP2 0.519 treat2
UTRN 0.502 treat4
REPS2 0.481 treat2
PKP4 0.365 treat1
LAMC1 -0.529 treat2
PPIB 2.86 treat4 ")
library(tidyverse)
df %>% ggplot(aes(x= treatment, y = protein, fill = value)) +
geom_tile()

OR
library(echarts4r)
df |>
e_charts(protein) |>
e_heatmap(treatment, value) |>
e_visual_map(value)

Here is some example data.
dat <- data.frame(
protein=replicate(100, paste(sample(LETTERS, 4), collapse="")),
value=rnorm(100),
treatment=paste0("treat", sample(1:4, 100, replace=TRUE)),
stringsAsFactors=FALSE
)
Using ggplot2 you could do
library(ggplot2)
plt <- ggplot(dat, aes(treatment, protein, fill=value)) + geom_tile()
More options you can find here: https://www.r-graph-gallery.com/79-levelplot-with-ggplot2.html
However, I don't know how to deal with a lot of proteins to plot (as you mentioned). Do you need to see the names of the proteins?
EDIT: one possibility for 1000 proteins would be to make the chart really long, like so:
ggsave(
"long.pdf", plot=plt, device="pdf",
width=21, height=150, units="cm", limitsize=FALSE
)
This creates a PDF in the current folder. Using the zoom function of your PDF-Viewer, you can then navigate to the rows of interest.
EDIT 2: For more complex charts I (still) rely on base R. But maybe there are some ggplot-Style packages I am not aware of. A base R solution requires to convert the data into a matrix first. One approach would be to use a sparse matrix like this:
dim_x <- unique(dat$protein)
dim_y <- unique(dat$treatment)
map_x <- setNames(seq_along(dim_x), dim_x)
map_y <- setNames(seq_along(dim_y), dim_y)
library(Matrix)
mat <- sparseMatrix(
i=map_x[dat$protein], j=map_y[dat$treatment], x=dat$value,
dims=c(length(dim_x), length(dim_y)), dimnames=list(dim_x, dim_y)
)
Then you can use the base R heatmap function,
heatmap(as.matrix(mat))
or some more customizeable function like
library(pheatmap)
pheatmap(mat)
which both show dendograms.
library(tidyr)
long_df <- df |> pivot_longer(cols = c('black', 'white'), names_to = "X", values_to = "Z")
Slightly reorganised to keep the "Name" column name.
| Name | X | Z |
|---|---|---|
| Apple | black | 1 |
| Apple | white | 10 |
| Banana | black | 2 |
| Banana | white | 5 |
| Milk | black | 3 |
| Milk | white | 999 |
To produce a heatmap:
library(ggplot2)
long_df |> ggplot(aes(Name, X, fill = Z)) + geom_tile()
which is very skewed by the white milk value of 999.
This is a short article where the author shows a nice way to generate heatmaps from dataframes, it will only take you two minutes.
https://datascientyst.com/display-pandas-dataframe-heatmap/



