6

So I am having a similar problem to the one in this question but the solutions therein are of no use.

Consider a basic ContourPlot with an automatic BarLegend

ContourPlot[{Cos[y + x] x y}, {x, 0, 3}, {y, 0, 3}, PlotRange -> All, 
 PlotLegends -> BarLegend[Automatic], 
Epilog -> {{Red, Line[Table[{i, Cos[i]}, {i, 0., 3., .1}]]}}]

which gives the following, nice ContourPlot:

https://i.stack.imgur.com/yW3fK.jpg

However, when I try and add a LineLegend for the Epilog, ContourPlot cannot do so automatically. I have tried all suggestions in the link above and none of them work

ContourPlot[{Cos[y + x] x y}, {x, 0, 3}, {y, 0, 3}, PlotRange -> All, 
 PlotLegends -> 
 Column[{BarLegend[Automatic], 
LineLegend[{Directive[Red]}, {"Test"}]}], 
Epilog -> {{Red, Line[Table[{i, Cos[i]}, {i, 0., 3., .1}]]}}]

https://i.stack.imgur.com/1gmXW.jpg

How do I fix this? I want the BarLegend to be automatic, since it provides a nice, simple fit of values. However, even manually I have had no success with BarLegend not evaluating.

(As a sidenote, imgur is not accepting the pictures I have provided. Have put up links, if someone can fix, would be grateful).

OldTomMorris
  • 607
  • 3
  • 10

4 Answers4

4

PlotLegends can take a list of legends:

ContourPlot[{Cos[y + x] x y}, {x, 0, 3}, {y, 0, 3}, 
    PlotRange -> All, PlotLegends -> {
        BarLegend[Automatic], 
        Placed[LineLegend[{Directive[Red]}, {"Test"}], After]
        }, 
    Epilog -> {{Red, Line[Table[{i, Cos[i]}, {i, 0., 3., .1}]]}}]

By default one legend will go to the right, and one below, so I used Placed to put both on the right.

Brett Champion
  • 20,779
  • 2
  • 64
  • 121
  • I swear I tried placing a list in PlotLegends, but I can't see what mistake I made, I believe Column was the problem. Have now amended your comment as the answer. – OldTomMorris Aug 08 '18 at 10:03
3

Here is a work-around using separate ContourPlots:

p1 = ContourPlot[{Cos[y + x] x y}, {x, 0, 3}, {y, 0, 3}, 
  PlotRange -> All, 
  PlotLegends -> BarLegend[Automatic]];

p2 = ContourPlot[y == Cos[x], {x, 0, 3}, {y, 0, 3}, 
  ContourStyle -> Red, 
  PlotLegends -> LineLegend[{"Test"}]];

Show[p1, p2]

Will this be ok?

Marius Ladegård Meyer
  • 6,805
  • 1
  • 17
  • 26
  • Placed is not necessary since Show knows how to combine Legended with legends at the same position, although you can use it to fine tune the positioning. Also, you don't need to specify the color with LineLegend, LineLegend[{"Test"}] does exactly what you want, and you only have to specify the color in one place. – rcollyer Aug 07 '18 at 16:28
  • @rcollyer, thanks for the simplifications! I will modify my answer :) – Marius Ladegård Meyer Aug 07 '18 at 16:30
  • Actually, Show and Legended is the correct way of doing it: Show[Legended[p1, LineLegend[{Directive[Red]}, {"Test"}]]] – OldTomMorris Aug 07 '18 at 16:49
  • 1
    I think both are "correct", but use the one you find most suitable of course :) – Marius Ladegård Meyer Aug 07 '18 at 16:57
  • 1
    @OldTomMorris I agree with Marius, both are correct, the Legended method, though is a little simpler/less intensive. They both work just finr. – rcollyer Aug 07 '18 at 16:59
  • @MariusLadegårdMeyer (and rcollyer) Both work just fine for the MWE (which is all I can ask for) but imo using Legended means that one does not have to define a contour (and an equation) and can just use any list of points to superpose onto a contour. Anyway thank you both! – OldTomMorris Aug 07 '18 at 17:28
  • 1
    @OldTomMorris actually, Brett's answer is the correct one. Column was causing the confusion. – rcollyer Aug 07 '18 at 17:41
  • 1
    @rccollyer In that case, I have shifted the answer. Thanks also to you, though. – OldTomMorris Aug 08 '18 at 10:04
3

Each plot type allows only specific legends to be used with PlotLegends, for ContourPlot and DensityPlot it is BarLegend. So, it is getting confused when you add LineLegend. (Per Marius, there is a switchover to LineLegend when only specific contours are used, e.g. f == g form of input to ContourPlot.)

The correct way is to use Legended to add the additional legend:

Legended[
 ContourPlot[{Cos[y + x] x y}, {x, 0, 3}, {y, 0, 3}, 
  PlotRange -> All, PlotLegends -> BarLegend[Automatic], 
  Epilog -> {{Red, Line[Table[{i, Cos[i]}, {i, 0., 3., .1}]]}}]
 , 
 LineLegend[{Directive[Red]}, {"Test"}]
]
rcollyer
  • 33,976
  • 7
  • 92
  • 191
  • This the one. I just managed to concoct something from Marius' answer and comments and I used Show and Legended. Was about to post an answer when I see your simplified result. Thank you very much :) – OldTomMorris Aug 07 '18 at 16:53
1

Hacked it. The key was to use LegendLabel to label the BarLegend and then hack it into what I wanted.

ContourPlot[{Cos[y + x] x y}, {x, 0, 3}, {y, 0, 3}, PlotRange -> All, 
PlotLegends -> 
BarLegend[Automatic, 
 LegendLabel -> 
Placed[LineLegend[{Directive[Red]}, {"Test"}], Bottom]], 
Epilog -> {{Red, Line[Table[{i, Cos[i]}, {i, 0., 3., .1}]]}}]

The result is

https://i.stack.imgur.com/cORkJ.jpg

OldTomMorris
  • 607
  • 3
  • 10