# Filling gradually varied colors under a function curve

I would like to plot a figure with a top to bottom gradient like this: I drew this figure using Matlab. Is it possible to plot a similar one using Mathematica? I googled some posts, but I do not know how to do this. Is it possible to do it by "filling"? Thank you!

1. According to Bob's idea, I tried this code:

 mx[x_] = -100*x*Exp[-69.3147*x^2]; (*This is my function*)
Show[RegionPlot[
mx[x] <= y <= 0 || 0 <= y <= mx[x], {x, -0.5, 0.5}, {y, -5.5, 5.5},
ColorFunction -> "Rainbow", AspectRatio -> 0.75,
BoundaryStyle -> None], Plot[mx[x], {x, -0.5, 0.5}],
PlotStyle -> Directive[Darker[Blue], Thick]]


I got this figure: Why the right tail is incompleted? If we look the figure carefully, the peak position is also not perfectly match the curve.

1. According to Michael's and kglr's idea, I tried this code:

 mx[t_] = t*Exp[-69.3147*t^2]; (*This is my function*)
Get["https://pastebin.com/raw/gN4wGqxe"]
JetCM = With[{colorlist = RGBColor @@@ jetColors},
Blend[colorlist, #] &];
ParametricPlot[{t, y*mx[t]}, {t, -0.5, 0.5}, {y, 0, 1},
PlotRange -> All,
ColorFunction -> (JetCM[#2 + (25 #2^2 (#2 - 1/2) (1 - #2)^2)/(1 +
100 (#2 - 1/2)^2)] &), AspectRatio -> 0.75, Axes -> False,
BoundaryStyle -> {Thick, Black}] /.
Line[v_, opts___] :> Line[v[[2 ;; -2]], opts]


Then I got this figure: The curve is not smooth anymore.

1. By the way, how to fill an inverse raninbow color? I tried this:

 ColorFunction -> ColorData[{"Rainbow", "Reverse"}]


But it does not work.

• A related example appears in the documentation, but it's in the other direction: Plot[Sin[x], {x, 0, 2 Pi}, ColorFunction -> Function[{x, y}, Hue[x]], Filling -> Axis, FillingStyle -> Automatic] – flinty Jun 23 at 13:22
• Increase the PlotPoints to get a smoother curve. – flinty Jun 24 at 11:58

You can get the Matlab color scheme from this site, courtesy of @JasonB:

(*https://mathematica.stackexchange.com/a/64514/4999*)
Get["https://pastebin.com/raw/gN4wGqxe"]
JetCM = With[{colorlist = RGBColor @@@ jetColors},
Blend[colorlist, #] &];

ParametricPlot[{s, t Sin[s]}, {s, 0, 2 Pi}, {t, 0, 1},
ColorFunction -> (JetCM[#2 + (25 #2^2 (#2 - 1/2) (1 - #2)^2)/(
1 + 100 (#2 - 1/2)^2)] &),
AspectRatio -> 1, Axes -> False,
BoundaryStyle -> {Thick, Black}] /.
Line[v_, opts___] :> Line[v[[2 ;; -18]], opts]


It's probably easier just plotting sine twice and composing than to postprocess the boundary Line:

Show[
ParametricPlot[{s, t Sin[s]}, {s, 0, 2 Pi}, {t, 0, 1},
ColorFunction -> (JetCM[#2 + (25 #2^2 (#2 - 1/2) (1 - #2)^2)/(
1 + 100 (#2 - 1/2)^2)] &), AspectRatio -> 1, Axes -> False,
BoundaryStyle -> None],
Plot[Sin[s], {s, 0, 2 Pi}, PlotStyle -> {Thick, Black}]
]


I'm not sure how the Matlab scaling of the color gradient was done. It seemed to require some funky transformation to approximate the OP's image. One can simply use ColorFunction -> (JetCM[#2] &) if the exact gradient is not needed.

Both figures look like this: • Hi, Michael. Thank you for your methods. I tried your code, but the curve is not smooth anymore. Please see above, I just updated this post. :_) – Mr.2023 Jun 24 at 2:54
• @Mr.2023 Increase PlotPoints. For example PlotPoints -> 30. (Probably don't need /. Line[v_, opts___] :> Line[v[[2 ;; -2]], opts]....or use something like /. Line[v_, opts___] :> Line[v[[2 ;; -32]], opts]) – Michael E2 Jun 24 at 3:02
• Michael, it works. Now the curve becomes smooth.:-) Do you know how to fill an inverse Rainbow color? I mean that fill red color in down part and blue color up part. – Mr.2023 Jun 24 at 3:07
• @Mr.2023 In the ColorFunction, the argument #2 is scaled to run from 0 to 1. So change each instance of #2 to 1 - #2. – Michael E2 Jun 24 at 3:09
• Michael, Thank you for your help. Used your method, I got the final figure what I expected. :_) Have a nice day! – Mr.2023 Jun 24 at 3:14

Use RegionPlot for the filling

Show[
RegionPlot[
0 <= y <= Sin[x] && 0 <= x <= Pi ||
Sin[x] <= y <= 0 && -Pi <= x <= 0,
{x, -4, 4}, {y, -1.1, 1.1},
ColorFunction -> "Rainbow",
AspectRatio -> 0.75,
BoundaryStyle -> None],
Plot[Sin[x], {x, -Pi, Pi}],
PlotStyle -> Directive[Darker[Blue], Thick]] • (+1), as this is more natural and faster than my DensityPlot. Also for the colour, try: ColorFunction -> Function[{x, y}, Hue[y]] to get a look closer to OP's question. – flinty Jun 23 at 14:03
• Hi, Bob. Thank you. I tried your method. It works but there exist some problems. Please see above, I just edit the post and show my progress.:_) – Mr.2023 Jun 24 at 2:21

It's possible to do this with a density plot if you're prepared to plug in the inequalities:

Show[
DensityPlot[
If[(0 < y < Sin[x]) || (Sin[x] < y < 0), y, ∞], {x, -π, π}, {y, -1, 1},
ColorFunction -> Function[{x, y}, Hue[x]], PlotPoints -> 30]
, Plot[Sin[x], {x, -π, π}, PlotStyle -> {Black, Thick}]
] • +1. You can also plot y and use e.g. RegionFunction -> Function[{x, y}, (y > 0 && y < Sin[x]) || (y < 0 && y > Sin[x])] – C. E. Jun 23 at 14:46
• Or you can use ConditionalExpression as well: ConditionalExpression[y, (0 < y < Sin[x]) || (Sin[x] < y < 0)] – C. E. Jun 23 at 14:52
ParametricPlot[{x, t Sin[x]}, {x, -π, π}, {t, 0, 1},
AspectRatio -> 1,
ColorFunction -> (ColorData["Rainbow"][#2] &),
MeshFunctions -> {#4 &}, Mesh -> {{1}},
MeshStyle -> Directive[Thick, Opacity, Black], Axes -> False,
BoundaryStyle -> None] With the second example in OP:

mx[x_] := -100 x Exp[-69.3147*x^2];

ParametricPlot[{x, t mx[x]}, {x, -0.5, 0.5}, {t, 0, 1},
AspectRatio -> 1, ColorFunction -> (ColorData["Rainbow"][#2] &),
MeshFunctions -> {#4 &}, Mesh -> {{1}},
MeshStyle -> Directive[Thick, Opacity, Black], Axes -> False,
BoundaryStyle -> None, PlotPoints -> 50, PlotRange -> All] Use ColorFunction -> (ColorData[{"Rainbow", "Reverse"}][#2] &) to get At the cost of some eye strain to find the right scaling ranges, we can use "VisibleSpectrum" to get close to the picture in OP:

colorFunction = ColorData["VisibleSpectrum"][
If[# <= 0, Rescale[#, {-1, 0}, {450, 510}], Rescale[#, {0, 1}, {550, 660}]]] &;

ParametricPlot[{x, t Sin[x]}, {x, -π, π}, {t, 0, 1},
AspectRatio -> 1,
ColorFunction -> (colorFunction[#2] &),
MeshFunctions -> {#4 &},
Mesh -> {{1}},
MeshStyle -> Directive[Thick, Opacity, Black],
ColorFunctionScaling -> False,
Axes -> False,
BoundaryStyle -> None] And for the second example in OP:

colorFunction = ColorData["VisibleSpectrum"][If[# <= 0,
Rescale[#, {-5, 0}, {450, 510}], Rescale[#, {0, 5}, {550, 660}]]] &;

ParametricPlot[{x, t mx[x]}, {x, -0.5, 0.5}, {t, 0, 1},
AspectRatio -> 1, ColorFunction -> (colorFunction[#2] &),
MeshFunctions -> {#4 &}, Mesh -> {{1}},
MeshStyle -> Directive[Thick, Opacity, Black],
ColorFunctionScaling -> False, Axes -> False, BoundaryStyle -> None,
PlotRange -> All, PlotPoints -> 50] • Hi, kglr. Thank you for your help. I tried the "ParametricPlot" method, but new problems apear. I just updated this post and show my progress of this problem. Could you read it and show me some possible solutions? :-) – Mr.2023 Jun 24 at 2:59
• Hi, kglr. Thank you! I got it. :_) – Mr.2023 Jun 24 at 3:20
• @Mr.2023, to get a smoother curve use a large value for PlotPoints, e.g.,PlotPoints -> 100. An for reversing the color function use ColorFunction -> (ColorData[{"Rainbow", "Reverse"}][#2] &). – kglr Jun 24 at 3:20

We can also use a LinearGradientImage as the setting for PlotStyle:

mx[x_] := -100 x Exp[-69.3147*x^2];

ParametricPlot[{x, t mx[x]}, {x, -0.5, 0.5}, {t, 0, 1},
AspectRatio -> 1, MeshFunctions -> {#4 &}, Mesh -> {{1}},
MeshStyle -> Directive[Thick, Opacity, Black], Axes -> False,
BoundaryStyle -> None, PlotPoints -> 50, PlotRange -> All,
PlotStyle -> Opacity[1, Texture[LinearGradientImage[{Top, Bottom} -> "Rainbow"]]],
TextureCoordinateFunction -> ({#1, #2} &)] Use LinearGradientImage[{Top, Bottom} -> ColorData[{"Rainbow", "Reversed"}]] or LinearGradientImage[{Bottom, Top} -> "Rainbow"] to get: • yes.Thank you:_) – Mr.2023 Jun 24 at 3:42