3
$\begingroup$

Suppose I have plot a ListDensityPlot graph, the value of the density is between xmin and xmax, and the change of the plot color is given by Log[x/xmin]/Log[x/xmax]. Now I want to create a corresponding legend, how to achieve this?

Let xmin=0.3, xmax=15, the scaling of the color should vary according to the log scale, not linear, the effect should more or less look like this:

enter image description here

$\endgroup$
  • $\begingroup$ A concrete example might be useful here. Is the issue primarily the scaling in the legends or simply the desire for two legends, each of which you can figure out the details yourself? $\endgroup$ – Mr.Wizard Mar 3 '17 at 3:10
  • $\begingroup$ @Mr.Wizard I mean the scaling. $\endgroup$ – an offer can't refuse Mar 3 '17 at 6:19
  • $\begingroup$ I don't see a V10-specific issue here. The question is valid in all versions, and all answers so far work in versions 9 & up (that I can test). The version-10 does not seem justified. $\endgroup$ – Michael E2 Mar 12 '17 at 22:02
4
$\begingroup$

Not sure if this is what you meant, but

xmin = 0.3; xmax = 15;
f[x_] := Log[x/xmin]/Log[x/xmax]
minmax = {f[xmin], f[xmax - 10^-10]};
cf = Blend[{Red, Green}, Rescale[f[#], minmax]] &;

then

BarLegend[{cf, {0.3, 15}}, ScalingFunctions -> {Log, Exp}]

enter image description here

$\endgroup$
  • $\begingroup$ I have no ScalingFunctions, my version is 10. $\endgroup$ – an offer can't refuse Mar 4 '17 at 0:56
  • $\begingroup$ @buzhidao This works in V10 & V9 for me. The automatic tick marks in V9 are a bit awkward, but BarLegend[{"SunsetColors", {0.3, 15}}, Ticks -> {0.3, 1, 3, 10, 15}, ScalingFunctions -> {Log, Exp}, LegendLayout -> "Row"] fixes that; and works in all versions V9-11. $\endgroup$ – Michael E2 Mar 12 '17 at 22:01
  • $\begingroup$ @MichaelE2 Thanks, it works with your modifications. $\endgroup$ – an offer can't refuse Mar 13 '17 at 0:42
2
+50
$\begingroup$

You can also generate the contours yourself (second argument to BarLegend). Here's a way to make a function that preserves the syntax of BarLegend but uses sort-of log scale:

$scalingFactor = E/2;
$scalingRange =
  Rescale[
   ($scalingFactor^Range[1, 10, .1]),
   $scalingFactor^{1, 10}
   ];
barLeg[{cf_, {xmin_, xmax_}}, ops___] :=

 BarLegend[{(cf@Rescale[#, {xmin, xmax}] &), {xmin - .01, xmax + .01}},
  Round[Rescale[$scalingRange, {0, 1}, {xmin, xmax}], .01],
  ops
  ]

And since we have enough contours it uses a continuous gradient. Here's your gradient:

barLeg[{
  Blend[
    Thread[{
      Rescale[{.3, 1, 3, 10, 15}, {.3, 15}],
      {Hue[.5, .5, .5], Hue[.6, 1, .5], Hue[0, 1, .8], Yellow, White}
      }], #] &,
  {.3, 15}},
 LegendLayout -> "Row"
 ]

sample gradient

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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