# Filling a curve to a vertical axis

I am preparing a figure for an article, and I would like very much to be able to fill a curve, but not under it, but to the vertical axis, i.e. to the left. Due to the meaning of the data I present, I cannot exchange the axes.

Here is a minimal example:

Plot[ArcCot[x], {x, 0, 1}, PlotRange -> {{0, 1.1}, {0.5, 2}}, AxesLabel -> {x, y}]


Can anyone think of a way of filling the curve to they axis? I find no mention of this kind of filling in the standard documentation.

• Duplicate of this? – bobthechemist Oct 4 '13 at 11:17
• Sorry everyone: that was a typing error. I surely meant "filling to the vertical axis, i.e. to the left". But thanks to it I have got even better understanding of the question than originally intended! – Dr_Zaszuś Oct 7 '13 at 8:34
• – Mr.Wizard Jan 10 '14 at 9:56

min = MinValue[ArcCot[x], 0 <= x <= 1, x];
Plot[{ArcCot[x], min}, {x, 0, 1}, PlotRange -> {{0, 1.1}, {0.5, 2}},
AxesLabel -> {x, y}, Filling -> {1 -> {2}}, PlotStyle -> {Automatic, None}]


• @mike-honeychurch. That's filling to the vertical axis indeed, thanks, that was what I was seeking. And in this aspect it's the same answer as that of Mike Honeychurch. – Dr_Zaszuś Oct 7 '13 at 8:41
• Choosing yours as the first simple answer to what I sought. – Dr_Zaszuś Oct 7 '13 at 8:56

This is my second answer, which is a rather different (and simpler) idea than my first one, namely, add a polygon that shades from a Line in the plot to a vertical axis at x = x0.

fillVertical[plot_, x0_: 0.] := plot /. Line[p_] :>
{{Opacity[0.2], Polygon[p ~Join~ {{N @ x0, p[[-1, 2]]}, {N @ x0, p[[1, 2]]}}]},
Line[p]}


The shading automatically takes the color (and other directives) from the plot styles. If the graph of a single function consists of several lines, then several polygons will be drawn and they might overlap. If the endpoints of the graph are not the extrema, then an edge of the polygon will cut through the graph.*

Example

fillVertical[
Plot[{ArcCot[x], 0.4 Sin[10 x] + x/2, 2 - x^2/3}, {x, 0.5, 2},
PlotRange -> {{0, 2.1}, {0., 2}}, AxesLabel -> {x, y}]]


**Note:* I thought about using MaxValue and MinValue, but it seemed unclear to me what the desired shading would be if the extrema do not occur at endpoints. I imagine that shading to a vertical axis would be sought only when the function is invertible (i.e., when $x$ is a function of $y$). So, for example, not the case of the sine graph shown above. It turns out fillVertical works for invertible Piecewise functions. The one below would be difficult with the standard filling options of Plot. (Observe that the extrema do occur at endpoints of Lines of the graph).

fillVertical[
Plot[Piecewise[{{x, 0 <= x <= 1}, {3 - x, 1 < x}}], {x, 0.5, 2},
PlotRange -> {{0, 2.1}, {0., 2}}, AxesLabel -> {x, y}]]


• Thank you, Michael. It is a nice solution indeed, what you proposed. And the curves you get are really pretty. I suppose that I would chose this one if I needed to fill several curves on the same plot. – Dr_Zaszuś Oct 11 '13 at 11:19
• To my mind, what you wish to obtain if the extrema do not occur at the endpoints, depends on what the nature of the curve you plot. In my case, the filling to the vertical axis represents the region in which a specific physical assumption is valid. So, if I had a sine curve like you show above, I would desire filling also through the white space under the curve between the minima. Although in my special case, such curves are not possible. Still, as a theoretical question, it is an interesting one. – Dr_Zaszuś Oct 11 '13 at 11:25
• @Szczypawka Thanks. You can use Max and Min on the coordinates in the Lines to get the bounding box of the curve and locations of the extrema. Theoretically, one could get all sorts of shading by modifying this method. It seems for your application that filling to the minimum is simplest. – Michael E2 Oct 11 '13 at 12:55
• Great solution. +1 – Mr.Wizard Jan 10 '14 at 9:58

Some of these answers seem overcomplicated.

min = MinValue[ArcCot[x], 0 <= x <= 1, x];
Plot[{ArcCot[x]}, {x, 0, 1}, PlotRange -> {{0, 1.1}, {0.5, 2}},
AxesLabel -> {x, y}, Filling -> {1 -> min}]


Edit

Frankly it is unclear to me what is wanted here. My comment is more directed toward the other answers than toward the actual question. But regarding the comment from @rm here is an example of filling to the right (if that is in fact what is required):

max = MaxValue[ArcCot[x], 0 <= x <= 1, x];
Plot[{ArcCot[x]}, {x, 0, 1}, PlotRange -> {{0, 1.1}, {0.5, 2}},
AxesLabel -> {x, y}, Filling -> {1 -> max}]


Happy to delete all this if none of it is what is being sought.

• @rm-rf, MichaelE2, Mike. Thank you, your answer is simple and elegant. I am sorry, I surely meant "left", but was just tired and wrote "right". Have already corrected. – Dr_Zaszuś Oct 7 '13 at 8:37
• So your comment is well directed towards the question I asked. – Dr_Zaszuś Oct 7 '13 at 8:38

A somewhat roundabout way (switch x,y; fill; switch x,y again):

With[{plot = Plot[ArcCot[x], {x, 0, 1}, PlotRange -> {{0, 1.1}, {0.5, 2}},
AxesLabel -> {x, y}]},
With[{pts = Cases[plot,
Line[p_] :> (p /. {x_Real, y_Real} :> {y, x}),
Infinity]},
Show[
ListLinePlot[pts, Filling -> Axis] /. {x_Real, y_Real} :> {y, x},
FilterRules[Options[plot], Options[Graphics]]]
]]


One advantage to this roundabout way is filling to the axis x = 0 when the Plot domain does not include it. Here we change the plot domain to {x, 0.5, 2}:

With[{plot = Plot[ArcCot[x], {x, 0.5, 2},
PlotRange -> {{0, 2.1}, {0., 2}}, AxesLabel -> {x, y}]},
With[{pts = Cases[plot,
Line[p_] :> (p /. {x_Real, y_Real} :> {y, x}),
Infinity]},
Show[
ListLinePlot[pts, Filling -> Axis, AxesOrigin -> {0, 0},
FilterRules[Options[plot], Cases[Options[ListLinePlot], Except[PlotRange -> _]]],
Options[plot, PlotRange] /. {rx_List, ry_List} :> {rx, ry}] /.
{x_Real, y_Real} :> {y, x},
Options[plot, PlotRange]]
]]


If placing the y axis to the right is desired, then the AxesOrigin can be used with ListLinePlot (when the coordinates are switched). Something like this:

Clear[x, y];
With[{plot = Plot[ArcCot[x], {x, 0.5, 2},
PlotRange -> {{0.4, 2.1}, {0., 2}}, AxesLabel -> {x, y}]},
With[{pts = Cases[plot,
Line[p_] :> (p /. {x_Real, y_Real} :> {y, x}),
Infinity]},
Show[ListLinePlot[pts, Filling -> Axis, Frame -> True, AxesOrigin -> {0, 2.1},
FilterRules[Options[plot], Cases[Options[ListLinePlot], Except[PlotRange -> _]]],
Options[plot,
PlotRange] /. {rx_List, ry_List} :> {rx, ry}] /. {x_Real, y_Real} :> {y, x},
Options[plot, PlotRange]]
]]


• That's filling to the vertical axis that I desired, thank you! And it's an intersting solution. Although a bit complicated, I should admit. Taking into account the other answers, I suppose it is possible to fill to x=0, when the figure does not include it if you fill not only to the min value, but between a max a and a min... – Dr_Zaszuś Oct 7 '13 at 8:47
• Having thought about it, I should add, that may indeed be an advantage. Suppose filling to x=0 if it is not included may be impossible with ordianary methods. So, thanks again. ) – Dr_Zaszuś Oct 7 '13 at 8:55

If you mean to fill everything to the right of the curve (you wrote "to the right", did not you?), try this:

    RegionPlot[y > ArcCot[x], {x, 0, 1.1}, {y, 0.5, 2},
AxesLabel -> {x, y}]


In response to your doubts: all this in your hands. This is without extra axes:

  RegionPlot[y > ArcCot[x], {x, 0, 1.1}, {y, 0.5, 2}, AxesLabel -> {x, y}, FrameTicks -> {Automatic, Automatic, None, None}]


This is without off-set:

RegionPlot$y > ArcCot$$x$, {x, 0, 1.1}, {y, 0.5, 2}, AxesLabel -> {x, y}, PlotRangePadding -> 0$$][3]


This is with a blue boundary, rather than gray one:

RegionPlot[y > ArcCot[x], {x, 0, 1.0}, {y, 0.5, 2}, AxesLabel -> {x, y}, PlotRangePadding -> 0, FrameTicks -> {Automatic, Automatic, None, None}, Frame -> {True, True, False, False}, BoundaryStyle -> {Blue, Thickness[0.005]}, PlotRange -> {{-0.1, 1.1}, {-0.1, 2.1}}]

and this is, if you like to have in blue only the line ActCot[x]:

    Show[{
RegionPlot[y > ArcCot[x], {x, 0, 1.0}, {y, 0.5, 2},
AxesLabel -> {x, y}, PlotRangePadding -> 0,
FrameTicks -> {Automatic, Automatic, None, None},
Frame -> {True, True, False, False},
PlotRange -> {{-0.1, 1.1}, {-0.1, 2.1}}],
Plot[ ArcCot[x], {x, 0, 1.0}, PlotStyle -> {Blue, Thickness[0.005]}]
}]


Have fun!

• Thanks, but using region plot, the way how the plot looks (I mean the axes at all 4 sides) also changes. And I suppose the solution with filling to minimum is easier. Still, your is also an interesting one. Thanks. – Dr_Zaszuś Oct 7 '13 at 8:49
• @Szczypawka That's in your hands: RegionPlot[y > ArcCot[x], {x, 0, 1.1}, {y, 0.5, 2}, AxesLabel -> {x, y}, FrameTicks -> {Automatic, Automatic, None, None}] – Alexei Boulbitch Oct 8 '13 at 11:18
• Right. That works. Although, I think, it would be nicer if I could fill to the axis itself: you see, now one has a small interval left (which is quite expected if one uses RegionPlot, surely). – Dr_Zaszuś Oct 11 '13 at 11:29
• @Szczypawka That's also in your hands. Try this: RegionPlot[y > ArcCot[x], {x, 0, 1.1}, {y, 0.5, 2}, AxesLabel -> {x, y}, PlotRangePadding -> 0]. Have fun. – Alexei Boulbitch Oct 14 '13 at 7:09
• Right. Still, you know, even if I put all the comments in one string: RegionPlot[y > ArcCot[x], {x, 0, 1.0}, {y, 0.5, 2}, AxesLabel -> {x, y}, PlotRangePadding -> 0, FrameTicks -> {Automatic, Automatic, None, None}, Frame -> {True, True, False, False}, PlotRange -> {{-0.1, 1.1}, {-0.1, 2.1}}] the plot looses the curve. If you evaluate the string, you will obtain a region with a grey boundary, which is not exactly what I would like to have. I mean like that the initial curve is hidden, which is no surprise if one uses RegionPlot. – Dr_Zaszuś Oct 14 '13 at 10:33

Using the function that I've previously defined here, we can do this:

Clear[x, y];

p = Plot[ArcCot[x], {x, 0, 1}, PlotRange -> {{0, 1.1}, {0.5, 2}}, AxesLabel -> {x, y}];

shadeBoundedArea[p, ArcCot[1] < y < ArcCot[x]]


• Thank you for the answer. Nice function! But I find that filling to a minimum value is just easier in this case. – Dr_Zaszuś Oct 7 '13 at 8:50
• Still there seems to be a strange artefact of filling near x=1... – Dr_Zaszuś Oct 11 '13 at 11:26
• @Szczypawka Yeah, I haven't had time to check that out. The function mostly works very nicely, though. (In the background this executes RegionPlot just as in Alexei's solution.) For your scenario other answers are better anyway. – C. E. Oct 11 '13 at 11:31
• You can fix that artefact by adding PlotPoints -> 100 to RegionPlot in shadeBoundedArea. – Chris Degnen Oct 15 '13 at 10:28

I know this thread is long time inactive, but Michael E2's excellent fillVertical function above helped me out a lot. I did need a more "density"-like fill, so I'm sharing my variant of it (using my novice-level Mathematica programming skills) which splits the Line into monotonic segments:

fillVertical2[plot_, x0_: 0.] := plot /. Line[p_] :>
Function[{mp},{{Opacity[0.2],
Polygon[mp ~Join~ {{N@x0, mp[[-1, 2]]}, {N@x0, mp[[1, 2]]}}]}, Line[mp]}] /@
SequenceCases[p, lp_ /; Less @@ lp[[All, 2]] || Greater @@ lp[[All, 2]]];


This gives a plot like

fillVertical2[Plot[Sin[x] + 0.3 x, {x, 0, 10}, PlotStyle -> Red]]