gyujun heo
gyujun heo

Reputation: 23

Gnuplot: plotting points with color based iris data

I have this iris data ...

5.1     3.5     1.4     0.2     Iris-setosa
4.9     3       1.4     0.2     Iris-setosa
7       3.2     4.7     1.4     Iris-versicolor
6.4     3.2     4.5     1.5     Iris-versicolor
7.1     3       5.9     2.1     Iris-virginica
6.3     2.9     5.6     1.8     Iris-virginica
.
.
.

and I got graph using gnuplot (plot 'c:\iris.data')

But I want points with color group by 5th column (iris-setosa, iris-versicolor, iris-virginica)

For example . . .

iris-setosa = color red, iris-versicolor= color green, iris-virginica = color blue

How can I get color graph?

Please answer . . . .

Upvotes: 1

Views: 625

Answers (3)

theozh
theozh

Reputation: 26123

In case you don't want to modify your original data (as required in Wrzlprmft's answer) or if you are using the palette already for some other purpose in the graph or if you need more than 255 colors (rarely), you can use the following.

Here, Christoph's lookup function is slightly modified because it would return index 4 if a colorname from the file is not in the list and it would give wrong results in the specially constructed case e.g. index("Test1") with the list "Test100 Test10 Test1".

You are basically looking for a mapping function for your own color names. This reminds me also to this question. You could also use the sum function to construct your lookup-table. And from gnuplot>=5.2.0 you could additionally use arrays.

In case you want a legend entry for each color you need to plot it in a loop and filter the data for each color accordingly.

Script:

### color according to colorname from file
reset session

$Data <<EOD
5.1     3.5     1.4     0.2     Iris-setosa
4.9     3       1.4     0.2     Iris-setosa
7       3.2     4.7     1.4     Iris-versicolor
6.4     3.2     4.5     1.5     Iris-versicolor
7.1     3       5.9     2.1     Iris-virginica
6.3     2.9     5.6     1.8     Iris-virginica
EOD

myColors     = 'Iris-setosa Iris-versicolor Iris-virginica'
myColorsRGB  = '0xff0000    0x00ff00        0x0000ff'
index(s)     = words(substr(myColors, 0, strstrt(myColors.' ', s.' ')))
myColor(col) = (_i=index(strcol(col)), _i ? int(word(myColorsRGB,_i)) : 0xcccccc)

set key out Left reverse noautotitle

set multiplot layout 2,1

    plot $Data u 1:2:(myColor(5)) w p pt 7 ps 2 lc rgb var

    myFilter(colD,colF,i) = strcol(colF) eq word(myColors,i) ? column(colD) : NaN
    plot for [i=1:words(myColors)] $Data u 1:(myFilter(2,5,i)):(myColor(5)) \
        w p pt 7 ps 2 lc rgb var ti word(myColors,i)

unset multiplot
### end of script

Result:

enter image description here

Upvotes: 0

Christoph
Christoph

Reputation: 48430

If you want to keep the string values in your data file, you can construct some kind of lookup-table with gnuplot, using the few string functions which gnuplot provides (see also Different coloured bars in gnuplot bar chart? for a similar use case):

IrisColors = 'Iris-setosa Iris-versicolor Iris-virginica'
index(s) = words(substr(IrisColors, 0, strstrt(IrisColors, s)-1)) + 1

set style fill solid noborder
set linetype 1 lc rgb 'red'
set linetype 2 lc rgb 'green'
set linetype 3 lc rgb 'blue'

plot 'iris.data' using 1:2:(index(strcol(5))) linecolor variable

Note, that the string comparison is case-sensitive, and that you cannot use strings with white spaces as single keys.

Upvotes: 1

Wrzlprmft
Wrzlprmft

Reputation: 4434

Replace your colours with numerical indices, e.g., like this:

5.1     3.5     1.4     0.2     0
4.9     3       1.4     0.2     0
7       3.2     4.7     1.4     1
6.4     3.2     4.5     1.5     1
7.1     3       5.9     2.1     2
6.3     2.9     5.6     1.8     2

A simple search-and-replace script should be able to do this for you.

Then you can use Gnuplot’s linecolor palette, e.g. as follows:

plot "iris.data" u 1:2:5 w p lc palette

To adjust the colours used like this:

set palette defined (0 "red", 1 "green", 2 "blue")

Note that while I chose to use the exact indices here, the palette definition is relative and I might as well have used:

set palette defined (-11 "red", -2 "green", 7 "blue")

Upvotes: 1

Related Questions