# How can I scale color bar and make it consistent with color of plot

for a minimal example, I have these two sets of data

data = {Table[{x, y, Sin[x y]}, {x, -4, 4}, {y, -4, 4, 0.1}],
Table[{x, y, 10 Sin[x y]}, {x, -4, 4}, {y, -4, 4, 0.1}]};


they are scaled 1/10 and I would like to plot them with different scaling like this

scaling = {1, 10};
Table[ListDensityPlot[Flatten[data[[j]], 1], PlotRange -> All,
ColorFunction -> (Blend[{RGBColor[0, 0, 0.7, 1],
RGBColor[0, 0.7, 1, 1], RGBColor[1, 1, 0, 0],
RGBColor[1, 0.5, 0, 1], RGBColor[0.6, 0, 0, 1]},
Rescale[#, {-scaling[[j]], scaling[[j]]}]] &),
ColorFunctionScaling -> False,
PlotLegends ->
BarLegend[{Automatic, {-scaling[[j]], scaling[[j]]}}]], {j, 1, 2}]


as you can see the color bar is not consisting of plot color. I tried to add ColorFunctionScaling -> True to the BarLegend but still did not work? how can I solve this stupid silly error of MMA? By the way, if I plot each case separately without using Table it is working fine?!!!

Define color function as a function beforehand.

data = {Table[{x, y, Sin[x y]}, {x, -4, 4}, {y, -4, 4, 0.1}],
Table[{x, y, 10 Sin[x y]}, {x, -4, 4}, {y, -4, 4, 0.1}]};
scaling = {1, 10};
cf[j_] := (Blend[{RGBColor[0, 0, 0.7, 1], RGBColor[0, 0.7, 1, 1],
RGBColor[1, 1, 0, 0], RGBColor[1, 0.5, 0, 1],
RGBColor[0.6, 0, 0, 1]},
Rescale[#, {-scaling[[j]], scaling[[j]]}]] &)

Table[ListDensityPlot[Flatten[data[[j]], 1], PlotRange -> All,
, ColorFunction -> cf[j]
, ColorFunctionScaling -> False,
PlotLegends ->
BarLegend[{Automatic, {-scaling[[j]], scaling[[j]]}}]], {j, 1, 2}]


As you indicated, the plots are fine when done individually so use Map rather than Table

\$Version

(* "13.0.0 for Mac OS X x86 (64-bit) (December 3, 2021)" *)

Clear["Global*"]

data = {Table[{x, y, Sin[x y]}, {x, -4, 4}, {y, -4, 4, 0.1}],
Table[{x, y, 10 Sin[x y]}, {x, -4, 4}, {y, -4, 4, 0.1}]};

Row[
ListDensityPlot[#,
PlotRange -> All,
ColorFunction -> (Blend[{
RGBColor[0, 0, 0.7, 1], RGBColor[0, 0.7, 1, 1],
RGBColor[1, 1, 0, 0], RGBColor[1, 0.5, 0, 1],
RGBColor[0.6, 0, 0, 1]}, #] &),
PlotLegends -> Automatic,
ImageSize -> 250] & /@
(Flatten[#, 1] & /@ data)]


Put the color function option value inside With[{j = j},...] to make sure that the value of j is injected inside Function construct:

Table[ListDensityPlot[Flatten[data[[j]], 1], PlotRange -> All,
ColorFunction -> (With[{j = j},
Blend[{RGBColor[0, 0, 0.7, 1], RGBColor[0, 0.7, 1, 1],
RGBColor[1, 1, 0, 0], RGBColor[1, 0.5, 0, 1],
RGBColor[0.6, 0, 0, 1]},
Rescale[#, {-scaling[[j]], scaling[[j]]}]] &] ),
ColorFunctionScaling -> False,
PlotLegends ->
BarLegend[{Automatic, {-scaling[[j]], scaling[[j]]}}]], {j, 1, 2}]


Alternatively, wrap ListDensityPlot[...] with With[{j = j},...]:

Table[With[{j = j},
ListDensityPlot[Flatten[data[[j]], 1], PlotRange -> All,
ColorFunction -> (Blend[{RGBColor[0, 0, 0.7, 1],
RGBColor[0, 0.7, 1, 1], RGBColor[1, 1, 0, 0],
RGBColor[1, 0.5, 0, 1], RGBColor[0.6, 0, 0, 1]},
Rescale[#, {-scaling[[j]], scaling[[j]]}]] &),
ColorFunctionScaling -> False,
PlotLegends -> Automatic]],
{j, 1, 2}]


both methods give

Note: PlotLegends -> BarLegend[{Automatic, {-scaling[[j]], scaling[[j]]}}] gives the same result.

• What does With[{j=j},...] do? It looks very strange to me
– Jojo
Dec 30, 2021 at 22:24
• @Joe, With[{j=j}, body] inserts values of the iterator j inside held expressions inside body . In this case, the rhs of the part of the body ColorFunction -> (stuff &), being a Function, has the attribute HoldAll -- which means stuff is maintained in unevaluated form, hence, any j that appears inside stuff stays unevaluated as j opposed to being replaced by the iterator value. For a simpler example, try SetAttributes[FOO, HoldAll]; and compare Table[FOO[i, j], {j, 1, 2}, {j, 1, 2}] vs Table[With[{i = i, j = j}, FOO[i, j]], {j, 1, 2}, {j, 1, 2}]`.
– kglr
Dec 31, 2021 at 6:04