# Annotations and line widths in Plots.jl heatmaps

**URL:** <https://discourse.julialang.org/t/annotations-and-line-widths-in-plots-jl-heatmaps/4259>\
**Category:** Visualization\
**Tags:** question, plotting\
**Created:** [June 14, 2017, 3:50am UTC](https://discourse.julialang.org/t/annotations-and-line-widths-in-plots-jl-heatmaps/4259 "2017-06-14T03:50:43Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)\
**Post date:** [June 14, 2017, 3:50am UTC](https://discourse.julialang.org/t/annotations-and-line-widths-in-plots-jl-heatmaps/4259/1 "2017-06-14T03:50:43Z")

</div>

One of the nicest features of heatmaps in the Python’s Seaborn module is the ability to annotate heatmaps with the values in the cells, the axes labels, and the line style separating the cells as you can see in these examples: [seaborn.heatmap — seaborn 0.12.2 documentation](http://seaborn.pydata.org/generated/seaborn.heatmap.html)

Given the following heatmap in Plots.jl:

```julia
using Plots

A = rand(10,10)
heatmap(A)

```

 ![](https://global.discourse-cdn.com/julialang/original/3X/9/6/965f71dd309ac4f096c9f503bc1d97f2d7136422.png)

Is there an option to annotate the cells? What about the line styles?

---

<div class="post-metadata">

**Author:** ![mkborregaard](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mkborregaard/32/556_2.png) [@mkborregaard](https://discourse.julialang.org/u/mkborregaard)\
**Post date:** [June 14, 2017, 5:07am UTC](https://discourse.julialang.org/t/annotations-and-line-widths-in-plots-jl-heatmaps/4259/2 "2017-06-14T05:07:38Z")

</div>

You can add the elements manually - check: [https://juliaplots.github.io/examples/pyplot/#annotations](https://juliaplots.github.io/examples/pyplot/#annotations) for the text annotations (use font to set the style), and you can overlay lines and use all the normal attributes to set the style [https://juliaplots.github.io/attributes/](https://juliaplots.github.io/attributes/) .

A nice trick is to use the userplot macro to create a recipe [https://juliaplots.github.io/recipes/](https://juliaplots.github.io/recipes/) - you’d need to creat two series (of type heatmap and path, using the `series` macro), and specify the annotations using the := syntax. You’d need Plots (not just RecipesBase) to define the recipe to have access to the `font` type.

EDIT: passing the annotations in a recipe will require some fiddling.

---

<div class="post-metadata">

**Author:** ![mkborregaard](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mkborregaard/32/556_2.png) [@mkborregaard](https://discourse.julialang.org/u/mkborregaard)\
**Post date:** [June 14, 2017, 8:25am UTC](https://discourse.julialang.org/t/annotations-and-line-widths-in-plots-jl-heatmaps/4259/3 "2017-06-14T08:25:49Z")

</div>

An example speaks louder than a thousand words.

```julia
using Plots
@userplot RecipesAreEasy
@recipe function f(x::RecipesAreEasy; annotationargs = ())
    y = x.args[1] #Get the input arguments, stored in x.args - in this case there's only one
    typeof(y) <: AbstractMatrix || error("Pass a Matrix as the arg to heatmap")

    grid := false # turn off the background grid
    
    @series begin # the main series, showing the heatmap
        seriestype := :heatmap
        y
    end

    rows, cols = size(y)

    #horizontal lines
    for i in 0:cols # each line is added as its own series, for clearer code
        @series begin
            seriestype := :path
            primary := false # to avoid showing the lines in a legend
            linecolor --> :white
            [i, i] .+ 0.5, [0, rows] .+ 0.5 # x and y values of lines
        end
    end

    for i in 0:rows
        @series begin
            seriestype := :path
            primary := false
            linecolor --> :white
            [0, cols] .+ 0.5, [i,i] .+ 0.5
        end
    end

    @series begin
        seriestype := :scatter
        markerstrokecolor := RGBA(0,0,0,0.) # make the points transparent - setting marker (or seriestype) to :none doesn't currently work right
        seriescolor := RGBA(0,0,0,0.) # do
        series_annotations := text.(1:(cols*rows), annotationargs...)
        primary := false
        repeat(1:cols, inner = rows), repeat(1:rows, outer = cols)
    end
end

```

Then

```julia
using Plots; pyplot() # currently broken in gr :-(
recipesareeasy(reshape(1:40, 8,5), annotationargs = (10, "Arial", :lightgrey)) #you can also use linecolor , linestyle, linewidth etc to modify the lines

```

![](https://global.discourse-cdn.com/julialang/original/3X/9/6/9615cef371e6502649120c5a8da09fa8d92ced10.png)

---

<div class="post-metadata">

**Author:** ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)\
**Post date:** [June 14, 2017, 2:03pm UTC](https://discourse.julialang.org/t/annotations-and-line-widths-in-plots-jl-heatmaps/4259/4 "2017-06-14T14:03:03Z")

</div>

Thanks @mkborregaard, this is really helpful! I appreciate the comments as well, they helped me a lot in understanding the machinery of plot recipes.

Should this recipe be part of PlotRecipes.jl? It may be useful to other users in the future, plus there is more customization that can be taken into account like the color of the annotations adapting to the heatmap (increase contrast), passing DataFrames, etc.

---

<div class="post-metadata">

**Author:** ![mkborregaard](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mkborregaard/32/556_2.png) [@mkborregaard](https://discourse.julialang.org/u/mkborregaard)\
**Post date:** [June 14, 2017, 7:33pm UTC](https://discourse.julialang.org/t/annotations-and-line-widths-in-plots-jl-heatmaps/4259/5 "2017-06-14T19:33:12Z")

</div>

I think it’d be nicer to allow `seriesannotations` and `linewidth / -style / -color` to have this functionality inside Plots. It’s intuitive and would give some keywords that don’t apply to heatmap a sensible use. That’s a lot more complex to adjust but a better long-term solution. Nice chance for a new contributor to make a high-value PR 🙂

---

<div class="post-metadata">

**Author:** ![kpapmath](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kpapmath/32/19859_2.png) [@kpapmath](https://discourse.julialang.org/u/kpapmath)\
**Post date:** [May 17, 2021, 9:13pm UTC](https://discourse.julialang.org/t/annotations-and-line-widths-in-plots-jl-heatmaps/4259/6 "2021-05-17T21:13:08Z")

</div>

Thank for the content. In order to place the values of the matrix in the output figure I have modified this line from ```  
series\_annotations := text.(1:(cols\*rows), annotationargs…)

````julia
to ```
series_annotations := text.(vec(round.(y,digits=3), annotationargs...)

````

Thanks again for sharing!!!
