# Adding a bar legend to a 3D plot indicating surface curvature by color

I want to color surfaces according to its Gaussian curvature, but the color bar is not consistent with the color.

How can I improve it?

Color a HyperbolicParaboloid according to its Gaussian curvature:

{surf, gaucurv} =
Through[SurfaceData[
"HyperbolicParaboloid", {"ParametricEquations",
"GaussianCurvature"}][3, 4]];
rng = {NMinValue[{gaucurv[u, v], -5 <= u <= 5 && -5 <= v <= 5},
{u, v}], NMaxValue[{gaucurv[u, v], -5 <= u <= 5 && -5 <= v <= 5},
{u, v}]};
ParametricPlot3D[surf[u, v], {u, -5, 5}, {v, -5, 5},
ColorFunction -> Function[{x, y, z, u, v},
ColorData["Rainbow"]@Rescale[gaucurv[u, v], rng]],
ColorFunctionScaling -> False, MeshStyle -> Opacity[0.25],
PlotLegends -> BarLegend[{"Rainbow", rng}], Boxed -> False,
Axes -> False, Method -> {"ShrinkWrap" -> True}]


https://reference.wolfram.com/language/ref/SurfaceData.html • try using PlotLegends -> BarLegend[{"Rainbow", rng}, ColorFunctionScaling -> True]?
– kglr
Dec 19, 2019 at 6:43
• @kglr . I just tried it, but it didn't work Dec 19, 2019 at 6:57

Replace PlotLegends -> BarLegend[{"Rainbow", rng}] with

PlotLegends -> BarLegend[{ColorData[{"Rainbow", rng}], rng}]


or with

PlotLegends -> BarLegend[{"Rainbow", rng}, Method -> ColorFunctionScaling -> True]


to get the correct colors in the legend:

ParametricPlot3D[surf[u, v], {u, -5, 5}, {v, -5, 5},
ColorFunction -> Function[{x, y, z, u, v},
ColorData["Rainbow"]@Rescale[gaucurv[u, v], rng]],
ColorFunctionScaling -> False,
MeshStyle -> Opacity[0.25],
Axes -> False, Boxed -> False,
PlotLegends -> BarLegend[{ColorData[{"Rainbow", rng}], rng}]],
Method -> {"ShrinkWrap" -> True}] ParametricPlot3D[surf[u, v], {u, -5, 5}, {v, -5, 5},
ColorFunction -> Function[{x, y, z, u, v},
ColorData["Rainbow"]@Rescale[gaucurv[u, v], rng]],
ColorFunctionScaling -> False,
MeshStyle -> Opacity[0.25],
Axes -> False, Boxed -> False,
PlotLegends -> BarLegend[{"Rainbow", rng}, ColorFunctionScaling -> True],
Method -> {"ShrinkWrap" -> True}]


same picture

A third approach is to move the legend outside ParametricPlot3D using Legended as in m_goldberg's answer:

Legended[ParametricPlot3D[surf[u, v], {u, -5, 5}, {v, -5, 5},
ColorFunction -> Function[{x, y, z, u, v},
ColorData["Rainbow"]@Rescale[gaucurv[u, v], rng]],
ColorFunctionScaling -> False, MeshStyle -> Opacity[0.25],
Axes -> False, Boxed -> False, Method -> {"ShrinkWrap" -> True}],
BarLegend[{"Rainbow", rng}]]


same picture

All three methods work both in Version 11.3 (Windows 10 6 bit) and Version 12.0 (Wolfram Cloud).

Here is another way. It gives a finer scale on the bar legend.

Legended[
ParametricPlot3D[surf[u, v], {u, -5, 5}, {v, -5, 5},
ColorFunction ->
Function[{x, y, z, u, v}, ColorData["Rainbow"] @ Rescale[gaucurv[u, v], rng]],
ColorFunctionScaling -> False,
MeshStyle -> Opacity[0.25],
Boxed -> False,
Axes -> False,
Method -> {"ShrinkWrap" -> True}],
BarLegend[{"Rainbow", {Floor[rng[], .01], Ceiling[rng[], .01]}}, 9]] 