6

I have noticed that Gnuplot produces ugly artefacts when dealing to filled elements.

One instance is in the palette of the next figure:

palette

Another example is when using filledcurves between two curves defined from points in ASCII files. In this case, you can see that rather than a real solid fill between the lines, the area is filled with number of strips, that only become apparent after zooming quite a bit, but that has very strong impact when rastering the image to png or similar:

strips

This seems to be independent on the terminal. I have tried postscrip, pdfcairo and even tikz. Is there anything that can be done to improve this, or is this a hard limitation of Gnuplot?

Pythonist
  • 1,937
  • 1
  • 14
  • 25
  • 1
    Nice picture! Unfortunately there isn't much you can do about this artefacts. They appear when you have two polygons touching each other. The same happens when plotting `with pm3d`, see my explanation in [problematic Moire pattern in image produced with gnuplot pm3d and pdf output](http://stackoverflow.com/a/18954245/2604213). That workaround however doesn't work in your case. I do have this very same issue for filledcurves on my todo list since a long time... A workaround, which I use, is to write a python script which generates polygon objects from your data files. Can post this later. – Christoph Jul 02 '15 at 12:17
  • Ok, so the idea is to preprocess the data to create a poligon out of the three columns and to plot it with filled curves, right? Does this produce a nice fill? If so, it looks about a good idea that this was indeed the default behaviour of Gnuopot under the hood, right? By the way 1, it would be nice if you could share that script. By the way 2, what do you mean by "my todo list"? Are you developer of Gnuplot? – Pythonist Jul 02 '15 at 21:10
  • 1
    Yes, I contributed some features and patches to gnuplot :) If you would define each curve as polygons with `set object polygon from ... to ... to ...` you get a nice fill. To create those polygon you need an external script (my script is of no need here, it was to specilized for my case). But then again you cannot use `lc palette frac`, and you don't get a colormap. So, that solution would be quite cumbersome, but not impossible. During the writing of my thesis those very same artifacts disturbed my a lot, so I took the long detour. And I always wanted to fix that in the code, but didn't yet. – Christoph Jul 02 '15 at 21:50
  • @Schorsch I tried to give a reasonable answer. – Christoph Jul 10 '15 at 21:35

1 Answers1

3

Unfortunately, this is an artifact due to antialiasing in the document viewer when you have two filled polygons touching each other. This happens with the filledcurves plotting style, which composes the filled area of many quadrangles, as well as with the pm3d style (as you can see in the colorbox, which shows the same artifacts). See also problematic Moire pattern in image produced with gnuplot pm3d and pdf output. for a concrete demo case.

There is a workaround, which however is very cumbersome. You must generate a filled polygon object with some script, fill that, use stats to determine the ranges, plot an empty plot (see e.g. Gnuplot - how can I get a figure with no point on it ? (I want to have only the axes, the title and the x- and y- labels)).

I assume, that you have a data file with three columns, and you would plot them with

plot 'test.dat' using 1:2:3 with filledcurves

Using the following very crude python script

from __future__ import print_function
from numpy import loadtxt
import sys

M = loadtxt(sys.argv[1])
print('set object 1 polygon ', end='')
for i in range(0,len(M)):
    if (i == 0):
        print('from {0},{1} '.format(M[i][0], M[i][1]), end='')
    else:
        print('to {0},{1} '.format(M[i][0], M[i][1]), end='')
for i in range(len(M)-1,-1,-1):
    print('to {0},{1} '.format(M[i][0], M[i][2]), end='')

You can plot the filled curve with

# determine the autoscaling ranges
set terminal push
set terminal unknown
plot 'test.dat' using 1:2, '' using 1:3
set terminal pop

set xrange [GPVAL_X_MIN:GPVAL_X_MAX]
set yrange [GPVAL_Y_MIN:GPVAL_Y_MAX]
eval(system('python script.py test.dat'))
set object 1 polygon fillstyle solid noborder fillcolor rgb 'red'
plot NaN notitle

That, doesn't yet cover the problem with the jagged colorbox :(

Community
  • 1
  • 1
Christoph
  • 47,569
  • 8
  • 87
  • 187
  • Thanks for the elaborated answer. I have a comment. Do we really need an object? Isn't a somewhat cleaner solution to use the script to create such a poligon from the two curves, but then use a simple "plot 'crafted-data.dat' u 1:2 w filledcurves"? – Pythonist Jul 10 '15 at 21:49
  • No, filledcurves will always decompose your area in quadrangles. If I remember correctly, only those curves with the x1 or x2 option do not suffer from this. Plotting the areas properly requires changes of the internal gnuplot code. – Christoph Jul 10 '15 at 22:00
  • But the figure above (the first one) is an example of that, and it seems to work fine. I have to try it anyway to confirm. I wanted t do it, but this week was impossible. I'll let you know my test. – Pythonist Jul 10 '15 at 22:04
  • If you see those white lines depends also on the viewer and the zoom factor – Christoph Jul 10 '15 at 22:07
  • I tried my experiement (http://i.imgur.com/jdoxeVz.png) ). It's the same data as in the figure above, but one curve (blue) was plotted with `u X1:Y1:Y2` and the orange with `u X1:Y1`, but pre-processing the input file so that I create a poligon beforehand with **two lines** of shell scripting. What I learn from this is that Gnuplot uses different algorithms for `plot w fc` depending on the number of columns. Actually, I would suggest that the three column version is "buggy" and could be safely replaced by the other (doing internally the poligon construction that took me two lines). – Pythonist Jul 12 '15 at 07:06
  • Sorry, my comment didn't fit in one single comment. Do you think it would be worth to suggest this as an improvement to the developer team? Or do you foresee some instance where replacing the standard algorithm by this would create other problems? I think replacing internally many squares by a single polygon would be almost trivial and overcomes a problem that seems to be annoying to many users. – Pythonist Jul 12 '15 at 07:11