13
$\begingroup$

Bug introduced in 8 or earlier and persisting through 12.0


I used ListLinePlot to plot data from .csv files. However, the y-values from Graph 1 do not match to the y-values from Graph 2, which I think, is the problem in my graph. Image of the problem linked.

enter image description here

What do I have to do, to get a smooth filling between the two graphs? The best way for defining the filling area would be a straight line between the last points on the two graphs.

Note: The "highest" point on Graph 1 doesn't exist. It is added by Mathematica, when I'm using the filling option.

EDIT: Code added. Normally there are 5 Graphs in 1 Chart, but the filling should only be done between the "highest" and the "lowest" graphs, to show some kind of scatter band.

EDIT2: Thank you very much! I can't set your answer to the one which helped me, since there seems to be a problem with my login. The Polygon Workaround is really helpful!!!

Code: http://pastebin.com/yPbv3Swm

Data Example Graph 1: http://pastebin.com/raJdP5HF Data Example Graph 2: http://pastebin.com/ywDbMWkP Data Example Graph 3 (New): http://pastebin.com/G577G9gS

$\endgroup$
  • 4
    $\begingroup$ Please add the code you used to generate the graph, and a sample of your data. $\endgroup$ – MarcoB Sep 1 '15 at 14:42
  • $\begingroup$ The data you posted doesn't seem to be the data you plotted $\endgroup$ – m_goldberg Sep 1 '15 at 15:41
  • $\begingroup$ It looks like you created two accounts. You should ping the moderators and have them merged, that way you get the full benefits of the reputation you earned. $\endgroup$ – rcollyer Sep 1 '15 at 18:38
15
$\begingroup$

I have distilled a minimal dataset reproducing the problem:

data = {{{45.904`, 227.46`}, {46.012`, 222.72`}, {46.076`, 215.51`}, {46.107`, 
     206.26`}, {46.119`, 196.15`}, {46.119`, 186.97`}, {46.118`, 178.5`}, {46.104`, 
     168.16`}, {46.079`, 156.43`}}, {{45.912`, 212.72`}, {45.976`, 205.51`}, {46.007`, 
     196.26`}, {46.019`, 186.15`}, {46.019`, 176.97`}, {46.018`, 168.5`}, {46.004`, 
     158.16`}, {45.979`, 146.43`}}};
simplePlot = ListLinePlot[data]
filledPlot = ListLinePlot[data, Filling -> {1 -> {2}}]

plot

plot

Let us look at the first Line inside of the plots:

Cases[Normal@simplePlot, _Line, -1][[1]]
Cases[Normal@filledPlot, _Line, -1][[1]]
Complement[%[[1]], %%[[1]]]
Line[{{45.904, 227.46}, {46.012, 222.72}, {46.076, 215.51}, {46.107, 206.26}, {46.119, 
   196.15}, {46.119, 186.97}, {46.118, 178.5}, {46.104, 168.16}, {46.079, 156.43}}]

Line[{{45.904, 227.46}, {45.912, 227.109}, {46.012, 222.72}, {45.979, 226.438}, {46.076, 
   215.51}, {46.107, 206.26}, {46.119, 196.15}, {46.119, 186.97}, {46.118, 
   178.5}, {46.104, 168.16}, {46.079, 156.43}}]

{{45.912, 227.109}, {45.979, 226.438}}

Indeed there are two additional points in positions 2 and 4 in the case of the filled plot which are absent in the original dataset. The second extra point creates the obvious artifact on the plot; this point also is included in the Polygon which represents filling between the lines (at position 9):

poly = Cases[Normal@filledPlot, _Polygon, -1]
{Polygon[{{45.912, 212.72}, {45.976, 205.51}, {46.007, 196.26}, {46.019, 186.15}, {46.019,
     176.97}, {46.018, 168.5}, {46.004, 158.16}, {45.979, 146.43}, {45.979, 
    226.438}, {46.012, 222.72}, {45.912, 227.109}}]}

Apart of the incorrect extra point the Polygon is self-intersecting and its set of points simply does not allow to create correct vertical filling between the lines:

Graphics[{LightBlue, poly, Black, MapIndexed[Text[#2[[1]], #] &, poly[[1, 1]]]}, 
 AspectRatio -> 1/GoldenRatio]

plot

So addition of the Filling option makes both the lines and the filling on the plot incorrect. This is a bug and I recommend to report it to the official technical support.

Here is a workaround which demonstrates the correct vertical filling between the curves:

ListLinePlot[{data[[1]], data[[2]], data[[2, ;; 4]]}, Filling -> {1 -> {3}}, 
 PlotStyle -> {Automatic, Automatic, None}]

plot


Your specific goal

You wrote:

The best way for defining the filling area would be a straight line between the last points on the two graphs.

Actually it is impossible to achieve this goal with the Filling option of ListLinePlot because the latter always fills vertically. You need to create a Polygon and add it as Prolog to your plot:

ListLinePlot[data, Prolog -> {LightBlue, Polygon[Join[data[[1]], Reverse@data[[2]]]]}]

plot

$\endgroup$
  • $\begingroup$ By my reading of the docs this should work: "In filling between lists of points that do not line up, the stems start at points in the first list, and extend to positions that linearly interpolate between points in the second list. " This is obviously not true even in simpler (monotonic) cases $\endgroup$ – george2079 Sep 1 '15 at 17:40
  • 3
    $\begingroup$ Alexey, already on it. There are two issues here: 1. the extra points (I can't seem to make a simpler example) and 2. the filling which is due to the non-injective nature of the data. $\endgroup$ – rcollyer Sep 1 '15 at 18:19
  • $\begingroup$ @rcollyer I have boiled down the minimal example to data = {{{45.904, 220.46}, {45.999, 223.72}, {46.02, 235.51}}, {{45.912, 212.72}, {46.019,186.15}, {45.95, 146.43}}}; ListLinePlot[data, Filling -> {1 -> {2}}]. $\endgroup$ – Alexey Popkov Sep 1 '15 at 20:25
  • $\begingroup$ @AlexeyPopkov that's a nice data set, thanks. $\endgroup$ – rcollyer Sep 1 '15 at 20:31
  • $\begingroup$ @AlexeyPopkov: The polygon solution works really good for me. Since I'm using the Polygon solution, is Mathematica able to create a polygon around many graphs? Right now, there is a polygon created between 2 data. But if I'm adding another 3 plots (as I mentioned before, there are orginally 5 plots in 1 chart), can I create a polygon which uses always the "most-outside" values? I added a third dataset, that you can see what I mean. $\endgroup$ – user32741 Sep 2 '15 at 9:18
6
$\begingroup$
data = {{{45.904`, 227.46`}, {46.012`, 222.72`}, {46.076`, 
     215.51`}, {46.107`, 206.26`}, {46.119`, 196.15`}, {46.119`, 
     186.97`}, {46.118`, 178.5`}, {46.104`, 168.16`}, {46.079`, 
     156.43`}}, {{45.912`, 212.72`}, {45.976`, 205.51`}, {46.007`, 
     196.26`}, {46.019`, 186.15`}, {46.019`, 176.97`}, {46.018`, 
     168.5`}, {46.004`, 158.16`}, {45.979`, 146.43`}}};

Show[
 RegionPlot[
  Polygon[
   Flatten[
    {data[[1]], Reverse[data[[2]]]},
    1]],
  PlotStyle -> LightBlue,
  BoundaryStyle -> None],
 ListLinePlot[
  data,
  PlotStyle -> Thick]]

enter image description here

$\endgroup$
  • $\begingroup$ +1 although this RegionPlot form is still undocumented and the straightforward approach is a little shorter: Show[Graphics[{LightBlue,Polygon[Flatten[{data[[1]],Reverse[data[[2]]]},1]]},Frame->True,AspectRatio->1],ListLinePlot[data]]. $\endgroup$ – Alexey Popkov Sep 2 '15 at 1:59
  • $\begingroup$ Thank you for your help Bob Hanlon! $\endgroup$ – user32741 Sep 2 '15 at 9:00

Your Answer

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