11
$\begingroup$

According to Document of BarLegend,BarLegend will select equally spaced contours:

BarLegend[cf,contours]
generates a legend that identifies color ranges from the color function cf based on the set of contours

However, when I try something like:

BarLegend["LakeColors", #] & /@ Range[8, 13] // Row

the output:

enter image description here

the figure of spaced contours disappear when contours number>11. Why will this happen?how to avoid this and get spaced contours? I use Mathematica9 on Win7

$\endgroup$
4
  • 1
    $\begingroup$ From the docs, "BarLegend[cf,contours] may use a list of colors or a continuous spectrum depending on the density of contour values." So, this is as designed. $\endgroup$
    – rcollyer
    Jun 8, 2015 at 15:20
  • $\begingroup$ Ahhh~~Then is there anyway to disable the "continuous spectrum"? $\endgroup$
    – Harry
    Jun 8, 2015 at 15:35
  • $\begingroup$ There might be a hidden option for it, but I can't seem to find one. $\endgroup$
    – rcollyer
    Jun 8, 2015 at 16:42
  • 2
    $\begingroup$ It'd be helpful if the v10 BarLegend had an option to specify the color density separate from the tick density versus assuming it based on the # of ticks. Changes to the v10 BarLegend affected me the opposite way where I wanted a continuous color gradient with less than 11 ticks but the BarLegend kept returning a segmented color gradient. $\endgroup$
    – rivercfd
    Oct 30, 2015 at 18:44

4 Answers 4

11
$\begingroup$
makeContours[barLegend_BarLegend] /; (Length[barLegend] =!= 2) := barLegend

makeContours[barLegend_BarLegend] := 
 Module[{colorScheme = barLegend[[1]], contourCount = barLegend[[2]]},
  If[IntegerQ[contourCount] && contourCount > 11 && 
    DataPaclets`ColorDataDump`colorSchemeNameQ[colorScheme], 
   ToExpression[
    MakeBoxes[barLegend] /. 
      RasterBox[colors_, scale_] :> 
       RasterBox[List@*List @@@ ColorData[colorScheme] /@ Subdivide[contourCount], scale] /. 
      (InterpretationFunction :> _) -> (InterpretationFunction :> (# &))],
   barLegend]]

makeContours@BarLegend["LakeColors", #] & /@ Range[8, 20] // Row

OUT

$\endgroup$
2
  • $\begingroup$ well done! I feel like I should delete my answer now, but it does contain some interesting information about the hidden options underlying this. $\endgroup$
    – Verbeia
    Oct 30, 2015 at 21:27
  • $\begingroup$ @Verbeia Thanks. You should definitely keep your answer posted. It not only contains interesting informations about additional options, but also how one might try to change the way BarLegend is created, although that seems to be the tougher road in this case. $\endgroup$
    – Karsten7
    Oct 30, 2015 at 21:42
4
$\begingroup$

Although there are hidden options to the underlying function (Charting`iBarLegend) that seem to address the required functionality, there does not seem to be any way to get the user-exposed function BarLegend to react to them. The following did not change the presentation of the test cases you provided, and neither did attempts to pass some promising-sounding options directly through BarLegend. For example the following did not change anything:

BarLegend["LakeColors", 12, "SmoothRange" -> False]

I suspect that there is no way to get the desired effect in current versions of Mathematica using straightforward options, though I could be wrong. And as Karsten's excellent answer shows, it is possible to force the issue by constructing the raster manually.

SetOptions[Charting`iBarLegend, ShowContours -> True]

{ColorFunctionScaling -> Automatic, ImageSize -> Automatic, 
 ImageSizeAction -> Automatic, RoundingRadius -> Automatic, 
 FrameStyle -> Automatic, Alignment -> Automatic, 
 Spacings -> Automatic, Scrollbars -> False, ScrollPosition -> {0, 0},
  Background -> Automatic, ContentPadding -> True, 
 DefaultLabelStyle -> {}, "Orientation" -> "Column", 
 Charting`AxesLabelRotate -> True, Charting`AxisAnnotation -> None, 
 Charting`AxisFactor -> None, Charting`AxisAppearance -> Automatic, 
 Charting`AxisLabel -> None, Charting`LabelSide -> Automatic, 
 Charting`PadLabels -> Automatic, Charting`RotateLabels -> False, 
 Charting`TickAnnotations -> None, Charting`TickSide -> Automatic, 
 Charting`TickLabels -> Automatic, Charting`TickLengths -> Automatic, 
 Charting`TickMarkers -> Automatic, Charting`TickWrappers -> None, 
 Charting`RotateTicks -> 0, AxesLabel -> None, AxesStyle -> Automatic,
  Frame -> True, FrameStyle -> Automatic, 
 LabelingFunction -> Automatic, Ticks -> Automatic, 
 TicksStyle -> Automatic, AspectRatio -> Automatic, 
 ScalingFunctions -> {Identity, Identity}, BaseStyle -> {}, 
 "LegendMethod" -> "Fixed", "Density" -> "Continuous", 
 "SmoothRange" -> True, "AxesPriority" -> Automatic, 
 "Sorting" -> True, "ContourMethod" -> "Graphics", 
 "RenderMode" -> Automatic, "LegendItemLayout" -> Automatic, 
 "PinningPoint" -> None, "StyledContours" -> None, 
 "ShowContours" -> True, PlotTheme -> "Mathematica"}
$\endgroup$
3
$\begingroup$

It's probably obvious to people with more experience than I, but since it took me a while to figure out:

If you want to modify Karsten's excellent answer above to produce horizontal BarLegends you need to take three inputs, transpose the matrix used in RasterBox, and add the LegendLayout->Row option to the function call:

makeContours[barLegend_BarLegend] /; (Length[barLegend] =!= 3) := barLegend

makeContours[barLegend_BarLegend] := 
Module[{colorScheme = barLegend[[1]], contourCount = barLegend[[2]]},
  If[IntegerQ[contourCount] && contourCount > 11 && 
    DataPaclets`ColorDataDump`colorSchemeNameQ[colorScheme], 
   ToExpression[
    MakeBoxes[barLegend] /. 
      RasterBox[colors_, scale_] :> 
       RasterBox[Transpose[List@*List @@@ 
      ColorData[colorScheme] /@ Subdivide[contourCount]], 
     scale] /. (InterpretationFunction :> _) -> \
    (InterpretationFunction :> (# &))], barLegend]]

 makeContours@BarLegend["LakeColors", #, LegendLayout -> "Row"] & /@ 
 Range[8, 20] // Row

horizontal BarLegends

One additional note. If in OS X you export one of these bar legends to pdf, the discrete color blocks will disappear and you'll be back to a smooth gradient. Frustrating! This is because of a bug in Mathematica's pdf export, described here along with the unfortunate solution: PDF exports of ArrayPlot's are fuzzy (OS X) .

$\endgroup$
2
$\begingroup$

Analysis

In Mathematica 10.1 this is hard-coded in Legending`LegendDump`iColorBandLegend.

Needs["GeneralUtilities`"]

PrintDefinitions @ Legending`LegendDump`iColorBandLegend

wherein appears:

cthreshold = 11

and later:

vdensity =
  If[vnumberofticks > cthreshold || moptShowContours === None, 200, cnumber - 1]

It happens that this function hands off to yet another internal function:

PrintDefinitions @ Legending`LegendDump`iColorGradientLegend

But in doing so it passes the density value as a Method option, and in iColorGradientLegend the Method supersedes other options. So we're going to have to modify something to get around this. iColorBandLegend seems like the obvious choice as it is the origin of the problem.

Patch

BarLegend[] // ToBoxes;  (* preload; do not remove! *)

With[{dv := DownValues[Legending`LegendDump`iColorBandLegend]},
  dv = dv /. HoldPattern[cth : Legending`LegendDump`cthreshold = _] :> (cth = 35);
]

Test:

BarLegend["LakeColors", #] & /@ Range[8, 16] // Row

enter image description here

$\endgroup$

Your Answer

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

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