2
$\begingroup$

Currently, I have the following

BarLegend[{colourScheme, {0, 10}}, {0.1, 5, 5.5}]

enter image description here

The contours are evenly distributed across the colourbar. I want them to sit where the corresponding tick values are (so 0.1 should be very close to the bottom, 5 should be right in the middle, etc.). How do I do this?

Thanks!

$\endgroup$
2
  • $\begingroup$ Welcome to the Mathematica Stack Exchange. What is the value at the top of the scale? Is this a compressed scale of some kind? Why is 5 sitting right in the middle? What is colourScheme? $\endgroup$
    – Syed
    Commented Jan 20 at 2:20
  • $\begingroup$ Welcome to Mathematica.SE! I hope you will become a regular contributor. To get started, 1) take the introductory tour now, 2) when you see good questions and answers, vote them up by clicking the gray triangles, because the credibility of the system is based on the reputation gained by users sharing their knowledge, 3) remember to accept the answer, if any, that solves your problem, by clicking the checkmark sign, and 4) give help too, by answering questions in your areas of expertise. $\endgroup$
    – bbgodfrey
    Commented Jan 22 at 13:55

3 Answers 3

2
$\begingroup$

The following provides what appears to be requested.

BarChart[{10, 5.5, 5, 0.1}, ChartLayout -> "Overlapped", 
    ImageSize -> Tiny, Axes -> False, AspectRatio -> 4, 
    ColorFunction -> "Rainbow", ChartLabels -> 
    Placed[{"10.", "5.5", "5.0", "0.1"}, {{1, 1}, {-.5, .5}}]]

enter image description here

If eliminating the top label is desired, replace "10." by Null. Colors can be changed by replacing ColorFunction -> "Rainbow" by a custom ChartStyle, for instance ChartStyle -> {Red, Green, Cyan, Purple}.

enter image description here

$\endgroup$
1
  • $\begingroup$ That does the trick. Quite surprising Mathematica doesn't have an inbuilt option to do this, but alas. Thanks! $\endgroup$ Commented Jan 22 at 13:19
2
$\begingroup$
ClearAll[contourLegend]

The function contourLegend takes Graphics options and options to control ticks, tick labels and legend orientation:

Options[contourLegend] = Join[
   {"Ticks" -> Automatic, 
    "TickLabels" -> Automatic, 
    "TickLengths" -> Automatic, 
    "TickSide" -> Right, 
    "TickDirection" -> "Out", 
    "RotateLabel" -> False, 
    "Appearance" -> "Vertical"},
  Options[Graphics]];

The first two arguments specify the color scheme and contour levels, which are used to construct rectangles with appropriate colors.

contourLegend[{cs_, range_ : {0, 1}}, contours_, opts : OptionsPattern[]] :=
 Module[{$rects, $ticks, $tvals, $tlbls, $tlngths, $rot,
   $cl = Join[{range[[1]]}, contours, {range[[2]]}],
   $wdth = -Subtract @@ range /15,
   $tr = OptionValue["Appearance"] /.
      {Automatic | "Vertical" | "Column" -> Identity, _ -> Reverse},
   $tr2 = OptionValue["TickSide"] /. 
      {Right | After | Above | Top | Automatic -> Identity, _ -> Reverse},
   $clrs = ColorData[{cs, range}] /@ 
     Join[{range[[1]]}, MovingAverage[contours, 2], {range[[2]]}]},
  $tvals = OptionValue["Ticks"] /. Automatic -> $cl;
  $tlbls = OptionValue["TickLabels"] /. Automatic -> $tvals;
  $rot = OptionValue["RotateLabel"] /. 
     {False -> 0  Degree, True -> 90  Degree, x_ :> x};
  $tlbls = Map[Rotate[#, $rot] &] @ $tlbls;
  $tlngths = OptionValue["TickLengths"] /. Automatic -> 
     (OptionValue["Appearance"] /. 
          {Automatic|"Vertical"|"Column" -> .15, _ -> .015});
  $tlngths = If[ListQ @ OptionValue["TickLengths"], $tlngths, 
    OptionValue["TickDirection"] /. 
     {"In" -> {$tlngths, 0}, "InOut" -> $tlngths {1, 1}, _ -> {0, $tlngths}}];
  $rects = Map[Rectangle @@ Transpose[$tr@{{0, $wdth}, #}] &] @ 
     Partition[$cl, 2, 1];
  $ticks = Thread[{$tvals, $tlbls, $tlngths}, List, 2];
  Graphics[MapThread[{EdgeForm[], #, #2} &] @ {$clrs, $rects}, 
   FilterRules[{opts}, Options[Graphics]],
   PlotRangePadding -> 0, 
   AspectRatio -> Automatic, 
   ImageSize -> {{50, All}, All},
   ImagePadding -> All,
   Frame -> True,
   FrameTicks -> $tr @ {$tr2 @ {None, $ticks}, {None, None}}]]

Examples:

Row[{contourLegend[{"Rainbow", {0, 1}}, {.2, .6, .7, .9}],
   contourLegend[{"Rainbow", {0, 10}}, {2, 6, 7, 9}],
   contourLegend[{"TemperatureMap", {0, 1}}, {.2, .6, .7, .9}],
   contourLegend[{"TemperatureMap", {0, 100}}, {10, 30, 50, 90}],
   contourLegend[{"TemperatureMap", {0, 100}}, {10, 30, 50, 90}, 
    "Ticks" -> {10, 30, 50, 90}, 
    "TickLabels" -> {"A", "BBBB", "CC", "label 4"}, 
    FrameLabel -> {{Style["legend", 18], None}, {None, None}}],
   contourLegend[{"TemperatureMap", {0, 100}}, {10, 30, 50, 90}, 
    "Ticks" -> {10, 30, 50, 90}, 
    "TickLabels" -> {"A", "BBBB", "CC", "label 4"}, 
    "TickSide" -> Left, "TickDirection" -> "InOut", 
    "TickLengths" -> .25, FrameTicksStyle -> Thick, 
    PlotLabel -> Style["legend", 16]]
   }, Spacer[20]] // Style[#, ImageSizeMultipliers -> {1, 1}] &

enter image description here

Column[{contourLegend[{"Rainbow", {0, 1}}, {.2, .6, .7, .9}, 
    "Appearance" -> "Horizontal"],
   contourLegend[{"Rainbow", {0, 10}}, {2, 6, 7, 9}, 
    "Appearance" -> "Horizontal"],
   contourLegend[{"TemperatureMap", {0, 1}}, {.2, .6, .7, .9}, 
    "Appearance" -> "Horizontal"],
   contourLegend[{"TemperatureMap", {0, 100}}, {10, 30, 50, 90}, 
    "Appearance" -> "Horizontal"],
   contourLegend[{"TemperatureMap", {0, 100}}, {10, 30, 50, 90}, 
    "Ticks" -> {10, 30, 50, 90}, 
    "TickLabels" -> {"A", "BBBB", "CC", "label 4"}, 
    "Appearance" -> "Horizontal", "RotateLabel" -> True, 
    FrameLabel -> {{None, None}, {Style["legend", 18], None}}],
   contourLegend[{"TemperatureMap", {0, 100}}, {10, 30, 50, 90}, 
    "Ticks" -> {10, 30, 50, 90}, 
    "TickLabels" -> {"A", "BBBB", "CC", "label 4"}, 
    "TickSide" -> Left, "TickDirection" -> "InOut", 
    "TickLengths" -> .025, "Appearance" -> "Horizontal", 
    "RotateLabel" -> True, FrameTicksStyle -> Thick, 
    PlotLabel -> Style["legend", 16]]
   }, Dividers -> All] // Style[#, ImageSizeMultipliers -> {1, 1}] &

enter image description here

With[{contours = {-1., -.8, .5, 1.25}}, 
 ContourPlot[2 Sin[x  y], {x, 0, π}, {y, 0, π}, 
  ColorFunction -> "Rainbow", Contours -> contours, ImageSize -> 300, 
  PlotLegends -> contourLegend[{"Rainbow", {-2, 2}}, contours]]]

enter image description here

With[{contours = {-1., -.8, .5, 1.25}}, 
 ContourPlot[2  Sin[x   y], {x, 0, π}, {y, 0, π}, 
  ColorFunction -> "Rainbow", Contours -> contours, ImageSize -> 300, 
  PlotLegends -> Placed[
     contourLegend[{"Rainbow", {-2, 2}}, contours, 
      "Appearance" -> Row, ImageSize -> {250, 50}, "RotateLabel" -> True], 
     Top]]]

enter image description here

$\endgroup$
1
$\begingroup$

When the second argument is specified, BarLegend produces equally-spaced contours with shading determined by the value of color function at specified contour levels.

To get a bar legend that behaves like ContourPlot (that is, shaded areas are proportional to differences between successive contour values) we can use (what else?) ContourPlot as follows:

barLegend[{cs_, range_: Automatic}, contours_, ticks_ : Automatic,
  opts : OptionsPattern[]] := 
 Module[{rmin = First[range /. Automatic -> {0, 1}], 
   rmax = Last[range /. Automatic -> {0, 1}]}, 
  ContourPlot[$y, {$x, 0, 1}, {$y, rmin, rmax}, opts, 
   ColorFunction -> cs, Contours -> contours, 
   AspectRatio -> (rmax - rmin), PlotRangePadding -> None, 
   Frame -> {{False, True}, {False, False}}, ContourStyle -> None, 
   FrameTicks -> {{None, {#, #, {0, .1}} & /@ (ticks /. 
         Automatic -> Join[{rmin}, contours, {rmax}])}, {None, None}}]]

Examples:

Row[{BarLegend[{"Rainbow", {0, 10}}, {0.1, 5, 5.5}, 
   LegendMarkerSize -> 400], 
  barLegend[{"Rainbow", {0, 10}}, 
   {0.1, 5, 5.5}, 
   {0.1, 5, 5.5, 10}, 
   ContourStyle -> None,
   ImageSize -> {100, 400}, 
   AspectRatio -> 20, 
   LabelStyle -> 14]}, 
  Spacer[30]]

enter image description here

Replace "Rainbow" with "TemperatureMap" to get

enter image description here

With[{contours = {-.8, -.9, 1, .75}},
 Row[ContourPlot[Sin[x  y], {x, 0, π}, {y, 0, π}, 
     ColorFunction -> "Rainbow", Contours -> contours, 
     ImageSize -> 300, PlotLegends -> #] & /@
   {Automatic, 
    barLegend[{"Rainbow", {-1, 1}}, contours, AspectRatio -> 20, 
     ImageSize -> {80, 300}, ImagePadding -> All]}]]

enter image description here

$\endgroup$
2
  • $\begingroup$ The barLegend function doesn't seem to work. The output just prints barLegend({"Rainbow", {-1, 1}}, {-0.8, -0.9, 1, 0.75}, AspectRatio -> 20, ImageSize -> {80, 300}, ImagePadding -> All). $\endgroup$ Commented Jan 22 at 13:17
  • $\begingroup$ Thank you @Sharplie12321. I updated with a correction - replaced range:Automatic with range_:Automatic. $\endgroup$
    – kglr
    Commented Jan 22 at 17:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.