Labels for levels in contour plot (Plots.jl)

question
plotting

#1

I would like to add custom labels to a contour plot, replacing the levels. Is this possible? MWE:

using Plots; pyplot() # other backend OK if necessary
using StatsBase
using Distributions
using StatsFuns

N = 100000
z = rand(MvNormal([1.0, 0.0], [1.0 0.5; 0.5 0.5]), N);
x = logistic.(z[1, :]);
y = logistic.(z[2, :]);
h = fit(Histogram, (x, y), closed = :left, nbins = (50, 50));

gap = trunc(Int, maximum(h.weights) / 9)
levels = 0:gap:(10*gap)
level_labels = map(x -> "$(x*10)%", 0:10)

contourf(midpoints(h.edges[1]),
         midpoints(h.edges[2]),
         h.weights';
         levels = levels)       # how to put level_labels in?

#2

I realized that for printed output, I don’t need contourf, contour would do just fine. But how can I

  1. make all the lines black, and
  2. put labels on them?

Eg continuing the above code,

contour(midpoints(h.edges[1]),
        midpoints(h.edges[2]),
        h.weights';
        color = "black",        # how to change contour lines to black? this does not work?
        colorbar = false,
        levels = levels)        # how to put level_labels in?

#3

I realized that I can go to the backend as a workaround:

using PyPlot
using StatsBase
using Distributions
using StatsFuns

N = 100000
z = rand(MvNormal([1.0, 0.0], [1.0 0.5; 0.5 0.5]), N);
x = logistic.(z[1, :]);
y = logistic.(z[2, :]);
h = fit(Histogram, (x, y), closed = :left, nbins = (20, 20));

gap = trunc(Int, maximum(h.weights) / 9)
levels = collect(0:gap:(10*gap))
level_labels = map(x -> "$(x*10)%", 0:10)

PyPlot.svg(true)
cs = contour(midpoints(h.edges[1]),
             midpoints(h.edges[2]),
             h.weights';
             colors = "black",
             levels = levels)
clabel(cs, fmt = Dict(zip(levels, level_labels)), inline = 1)

x


#4

A related (?) problem… I have tried to use Plots to do a 3d surface plot with contours (useful, e.g., in illustrating optimization problems). However, I was not able to freely choose the z-position of the contours – this seems to be hard-coded to z=0. If the minimum value of f(x,y) is “small” (close to zero or lower), the surface plot will often hide the contours. When I tried to learn Matplotlib some years ago, I found it was relatively straightforward to set the z-position of the contours, and I’d think this is very useful also in Plots.

[OK – perhaps this is possible in Plots – I just haven’t found any documentation of it.]


#6

Part solutions:
define constant color map:
color = cgrad([:black,:black,:black])
this seems to also work (though I’ve seen glitches with this)
color = :black

show contour labels
contour_labels = true

These usages seem to require the latest master.

I haven’t come across a way to use custom labels for the contour levels so far.