forecaster
forecaster

Reputation: 1159

labeling 2d contour plot from table in gnuplot

I need to create a 2D contour plot using gnuplot with data table. I'm not sure how to label the contours.

I cannot use splot feature to create contour labels because I would like to add 2D plots on top of contour plots.

Below is code to replicate to create a 2D contour plot. My question is how to create labels using the data table.

reset
f(x,y)=(x**2+y-11)**2+(x+y**2-7)**2
set xrange [0:5]
set yrange [0:5]
set isosample 250, 250
set table 'test1.dat'
splot f(x,y)
unset table

set contour base
set cntrparam levels disc 450,250,150,100,60,30,10,2 
unset surface
set table 'cont1.dat'
splot f(x,y)
unset table


reset session

set terminal wxt size 800,600 enhanced font 'Verdana,10' persist


set style arrow 2 head nofilled size screen 0.03,15 ls 2 lc rgb "blue"

set xrange [0:5]
set yrange [0:5]
unset key
#set palette rgbformulae 33,13,10

p 'cont1.dat' w l lt -1 lw 1.5

Here is the cont1.dat looks like based on running the above code. The final column is the label that I would like to have it the contour plot.

enter image description here

Upvotes: 0

Views: 2824

Answers (2)

theozh
theozh

Reputation: 25714

It's not clear to me whether you are talking about "labels" of the contour or "keys" (or legend) of the contours. Here is a minimized example for both possibilities. I assume you've just chosen a function for demo purposes but your data will be from a file.

A trick to avoid the gap in curves (without external script) is to skip 5 lines and set datafile commentschar " " and take columnheader(5). The lines like # Contour 0, label: 2 are then considered as data where the 5th column is your key. Apparently, the actual data is nevertheless (or luckily) not interpreted as comments although the commentschar is set to space.

Code:

### contour lines with labels
reset session

f(x,y)=(x**2+y-11)**2+(x+y**2-7)**2

set xrange [0:5]
set yrange [0:5]
set isosample 250, 250

set contour base
set cntrparam levels disc 450,250,150,100,60,30,10,2 
unset surface
set table $Contour
    splot f(x,y)
unset table

set style textbox opaque noborder

set multiplot layout 2,1
    plot $Contour u 1:2 w l lw 1.5 notitle, '' u 1:2:3 every 50 w labels boxed notitle

    set datafile commentschar " "
    plot for [i=1:8] $Contour u 1:2:(i) skip 5 index i-1 w l lw 1.5 lc var title columnheader(5)
unset multiplot
### end of code

Result:

enter image description here

Addition:

If you add the line

set key top left opaque box

and exchange the plot command to:

plot for [i=1:8] $Contour u 1:2 skip 5 index i-1 w l lw 1.5 lc 0 dt i title columnheader(5)

You will get the following:

Note that there are only 5 predefined dash types which will be repeated, however, you can define your own dash patterns (see help dashtype).

enter image description here

Upvotes: 2

maij
maij

Reputation: 4218

I think you want something like this:

datafile = 'cont1.dat'
stats datafile nooutput
plot for [i=0: STATS_blocks-1] datafile index i title columnhead(3) w l

The stats command collects some statistical information about the datafile, especially it counts the number of blocks. Blocks are separated by two empty lines, and each block corresponds to a different contour level.

The columnheads(3) command takes the entry in the third column of the first line in each block as title.

Unfortunately, in your case, because of the columnhead command, the first line is interpreted as header line and skipped for plotting. This leads to gaps in the resulting diagram:

with gaps

I would suggest some preprocessing to generate a headerline without using the first dataline. The simplest thing which worked for me was to remove the # at the beginning of the comment lines which start each block. I'm on Linux, so I use sed:

sed "s/# Contour/Contour/" -i cont1.dat

This can be called from gnuplot, and the final script looks like this:

reset

# We need the datafile several times
datafile = 'cont1.dat'

f(x,y)=(x**2+y-11)**2+(x+y**2-7)**2

set xrange [0:5]
set yrange [0:5]
set isosample 250, 250

# Generate data
set contour base
set cntrparam levels disc 450,250,150,100,60,30,10,2 
set view map
unset surface
set table datafile
splot f(x,y)
unset table

# Count blocks
stats datafile nooutput

system("sed \"s/# Contour/Contour/\" -i ".datafile)

# Plot each data block separatly and set the title to 
# the first entry of the third column of the respective block
plot for [i=0: STATS_blocks-1] datafile index i title columnhead(4) w l 

without gaps

One drawback: The datafile after the sed command contains some invalid lines "Contour 0, label:", without the comment hash # and without a label number. They are ignored by gnuplot because they don't contain valid data.

Upvotes: 1

Related Questions