diff --git a/DESCRIPTION b/DESCRIPTION
index 6fdb1eab80f2204de67b08110faf408f49d48f95..0bcdc97fa5e4c456a19c637cde46e0f911c2c73c 100644
--- a/DESCRIPTION
+++ b/DESCRIPTION
@@ -1,18 +1,9 @@
 Package: ranomaly
 Title: An R package grouping ANOMALY worflow functions
 Version: 1.0.0
-Author@R: 
-    c(person(given = "Sebastien",
-             family = "Theil",
-             role = c("aut", "cre"),
-             email = "sebastien.theil@inrae.fr"),
-      person(given = "Etienne",
-             family = "Rifa",
-             role = "aut",
-             email = "etienne.rifa@inrae.fr"))
-Author: Sebastien Theil [aut, cre],
-  Etienne Rifa [aut]
-Maintainer: Sebastien Theil <sebastien.theil@inrae.fr>, Etienne Rifa <etienne.rifa@inrae.fr>
+Author: Sebastien Theil [aut, cre], Etienne Rifa [aut]
+Maintainer: Sebastien Theil <sebastien.theil@inrae.fr>, Etienne Rifa
+    <etienne.rifa@inrae.fr>
 Description: rANOMALY use Amplicon Sequence Variant (ASV from Dada2
     package) as taxonomic unit, allowing an easy and relevant sequence
     tracking between different environments and/or projects.  Decontam
@@ -33,6 +24,7 @@ Imports:
     BiocGenerics,
     Biostrings,
     cluster,
+    ComplexHeatmap,
     dada2,
     DECIPHER,
     decontam,
@@ -83,7 +75,10 @@ Remotes:
     github::grunwaldlab/metacoder,
     github::mikelove/DESeq2,
     github::mixOmicsTeam/mixOmics
+Author@R: c(person(given = "Sebastien", family = "Theil", role = c("aut",
+    "cre"), email = "sebastien.theil@inrae.fr"), person(given = "Etienne",
+    family = "Rifa", role = "aut", email = "etienne.rifa@inrae.fr"))
 Config/testthat/edition: 3
 Encoding: UTF-8
 LazyData: true
-RoxygenNote: 7.2.3
+RoxygenNote: 7.3.1
diff --git a/NAMESPACE b/NAMESPACE
index ee9b190ce48213f52a426cd3a8d906283608bb8d..fbf7f3873512c29108c839362d647651aeb3dfaa 100644
--- a/NAMESPACE
+++ b/NAMESPACE
@@ -18,6 +18,7 @@ export(export_to_stamp_fun)
 export(fill_tax_fun)
 export(generate_phyloseq_fun)
 export(generate_tree_fun)
+export(heatmapDeseq2_fun)
 export(heatmap_fun)
 export(idTaxa_assign)
 export(idtaxa_assign_fasta_fun)
@@ -55,6 +56,7 @@ import(readr)
 import(readxl)
 import(reshape2)
 import(scales)
+import(stringr)
 import(tools)
 import(vegan)
 import(vroom)
@@ -62,6 +64,7 @@ importFrom(Biobase,AnnotatedDataFrame)
 importFrom(Biobase,fData)
 importFrom(BiocGenerics,estimateSizeFactors)
 importFrom(Biostrings,DNAStringSet)
+importFrom(ComplexHeatmap,pheatmap)
 importFrom(DECIPHER,AlignSeqs)
 importFrom(DESeq2,DESeq)
 importFrom(DESeq2,results)
diff --git a/R/heatmapDeseq2_fun.R b/R/heatmapDeseq2_fun.R
new file mode 100644
index 0000000000000000000000000000000000000000..e5d3cd0cc551fe968ea8bbad420bf8ceeddb167a
--- /dev/null
+++ b/R/heatmapDeseq2_fun.R
@@ -0,0 +1,108 @@
+#' heatmap for deseq2_fun output
+#'
+#' @param desq output of deseq2_fun
+#' @param phys the phyloseq object used for deseq2 analyse
+#' @param var Factor to test.
+#' @param workingRank Taxonomy rank used in deseq2_fun function.
+#' @param output Output directory
+#' @return Return a list object with heatmap plots and data matrix.
+#' @import futile.logger
+#' @import stringr
+#' @import phyloseq
+#' @importFrom ComplexHeatmap pheatmap
+#' @export
+
+heatmapDeseq2_fun <- function(desq, phys, var, workingRank, output = "./deseq/heatmap/") {
+  dir.create(output, recursive = TRUE)
+  PList = list()
+  for (i in names(desq)) {
+    PList[[i]] <- heatmapDeseq2_funSub(desq[[i]], phys, var, workingRank, i)
+    png(glue::glue("{output}/pheatmap-{i}.png"), width = 1200, height = 800, res = 150)
+    print(glue::glue("Output {i}"))
+    print(PList[[i]])
+    dev.off()
+  }
+  return(PList)
+}
+
+#' heatmap for deseq2_fun output
+#'
+#' @param desq output of deseq2_fun
+#' @param phys the phyloseq object used for deseq2 analyse
+#' @param var Factor to test.
+#' @param workingRank Taxonomy rank used in deseq2_fun function.
+#' @param i deseq subset name
+#' @return Return a list object with heatmap plots.
+#' @import futile.logger
+#' @import stringr
+#' @import phyloseq
+#' @importFrom ComplexHeatmap pheatmap
+
+heatmapDeseq2_funSub <- function(desq, phys, var, workingRank, i) {
+  tableDESeqSig <- desq[["table"]] |> subset(padj < 0.05) |> na.omit()
+
+  # remove unused taxa
+  psTaxaRelSig <- prune_taxa(row.names(tableDESeqSig),
+                             transform_sample_counts(phys, function(x) x/sum(x)))
+
+  # remove unused sample
+  keepSamp <<- stringr::str_split(i, "_vs_", simplify = TRUE)
+
+  psTaxaRelSig2 <- paste("psTaxaRelSigSubset <<- subset_samples(psTaxaRelSig, ",
+                         var, " %in% keepSamp)", sep = "")
+  eval(parse(text = psTaxaRelSig2))
+  psTaxaRelSigSubset <- subset_taxa(psTaxaRelSigSubset,
+                                    taxa_sums(psTaxaRelSigSubset) != 0)
+  pmatrix <- otu_table(psTaxaRelSigSubset) |>
+    data.frame() |>
+    as.matrix()
+  if (!taxa_are_rows(psTaxaRelSigSubset)) {
+    colnames(pmatrix) <- tax_table(psTaxaRelSigSubset)[, workingRank] |>
+      as.character()
+  } else {
+    rownames(pmatrix) <- tax_table(psTaxaRelSigSubset)[, workingRank] |>
+      as.character()
+  }
+
+  metadataSub <- sample_data(psTaxaRelSigSubset) |>
+    data.frame()
+  # print(metadataSub)
+
+  if (length(var) == 1) {
+    annotationCol <- data.frame(
+      var1 = metadataSub[, var[1]] |>
+        as.vector() |>
+        as.factor(),
+      check.names = FALSE)
+  } else {
+    annotationCol <- data.frame(
+      var1 = metadataSub[, var[1]] |>
+        as.vector() |>
+        as.factor(),
+      var2 = metadataSub[, var[2]] |>
+        as.vector() |>
+        as.factor(),
+      check.names = FALSE)
+  }
+
+  rownames(annotationCol) <- rownames(metadataSub)
+  colnames(annotationCol) <- var
+
+  annotationRow <- data.frame(
+    Phylum = tax_table(psTaxaRelSigSubset)[, "Phylum"] |>
+      as.factor()
+  )
+  if (taxa_are_rows(psTaxaRelSigSubset)) {
+    rownames(annotationRow) <- rownames(pmatrix)
+  } else {
+    rownames(annotationRow) <- colnames(pmatrix)
+  }
+  title <- i
+
+  pheat <- ComplexHeatmap::pheatmap(pmatrix, scale = "row",
+                                    annotation_col = annotationCol,
+                                    annotation_row = annotationRow,
+                                    main = title)
+
+  return(list(pheat=pheat,pmatrix=pmatrix))
+}
diff --git a/man/heatmapDeseq2_fun.Rd b/man/heatmapDeseq2_fun.Rd
new file mode 100644
index 0000000000000000000000000000000000000000..333bd8b68bc6f901b7fd8563da90b46a5ed5a028
--- /dev/null
+++ b/man/heatmapDeseq2_fun.Rd
@@ -0,0 +1,25 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/heatmapDeseq2_fun.R
+\name{heatmapDeseq2_fun}
+\alias{heatmapDeseq2_fun}
+\title{heatmap for deseq2_fun output}
+\usage{
+heatmapDeseq2_fun(desq, phys, var, workingRank, output = "./deseq/heatmap/")
+}
+\arguments{
+\item{desq}{output of deseq2_fun}
+
+\item{phys}{the phyloseq object used for deseq2 analyse}
+
+\item{var}{Factor to test.}
+
+\item{workingRank}{Taxonomy rank used in deseq2_fun function.}
+
+\item{output}{Output directory}
+}
+\value{
+Return a list object with heatmap plots and data matrix.
+}
+\description{
+heatmap for deseq2_fun output
+}
diff --git a/man/heatmapDeseq2_funSub.Rd b/man/heatmapDeseq2_funSub.Rd
new file mode 100644
index 0000000000000000000000000000000000000000..dc347fd8b5719a8650f6eff61bfd0dcc778d5d90
--- /dev/null
+++ b/man/heatmapDeseq2_funSub.Rd
@@ -0,0 +1,25 @@
+% Generated by roxygen2: do not edit by hand
+% Please edit documentation in R/heatmapDeseq2_fun.R
+\name{heatmapDeseq2_funSub}
+\alias{heatmapDeseq2_funSub}
+\title{heatmap for deseq2_fun output}
+\usage{
+heatmapDeseq2_funSub(desq, phys, var, workingRank, i)
+}
+\arguments{
+\item{desq}{output of deseq2_fun}
+
+\item{phys}{the phyloseq object used for deseq2 analyse}
+
+\item{var}{Factor to test.}
+
+\item{workingRank}{Taxonomy rank used in deseq2_fun function.}
+
+\item{i}{deseq subset name}
+}
+\value{
+Return a list object with heatmap plots.
+}
+\description{
+heatmap for deseq2_fun output
+}