Friday, September 30, 2011

Rotate a picture using gnuplot

Last time I promised rotating a picture using gnuplot will be talked. Today I come to realize my promise.Let us look at the script at first.
#Utility:Convert a rgb colorized image to a gray one
#Author:数声风笛离亭晚,我想潇湘君想秦!
#Email:qinjieli@gmail.com
#Usage:
##call "rotate.gnuplot" angle inputfile outputfile
#parameters:
##angle: the angle to be rotated
##inputfile: input filename (without ".png")
##outputfile: outputfilename (without ".png")
reset
angle=$0    #angle to be rotated
angle=angle*pi/180    #change degrees to radians
inputfile="$1.png"    #input file
outputfile="$2.png"    #ouput file
set size ratio -1
# Set the scales so that the unit has the same length
#on both the x and y axes
set lmargin 0    #nO margin
set rmargin 0
set tmargin 0
set bmargin 0
unset tics    #no tics and border line
unset border
#plot and get the size of the rotated picture
plot inputfile binary filetype=png rotate=angle w rgbima notitle
xmax=GPVAL_DATA_X_MAX
xmin=GPVAL_DATA_X_MIN
ymin=GPVAL_DATA_Y_MIN
ymax=GPVAL_DATA_Y_MAX
set xrange [xmin:xmax]    #set x and y range
set yrange [ymin:ymax]
set term png truecolor size (xmax-xmin),(ymax-ymin)    #set the terminal
set output outputfile
plot inputfile binary filetype=png rotate=angle w rgbima notitle
The script first plot the plot the rotated picture on screen. This plot has two functions, determining the size of the output picture and letting the user have view at the rotated picture. Save the script as "rotate.gnuplot", and then it can be called like this:
gnuplot> call "rotate.gnuplot" 30 input output
At last is one of our finished work.

Input picture file (initial file download from here)

Picture rotated by 30 degree using our script


Thursday, September 29, 2011

Crop picture using gnuplot

We talked about converting a rgb image to a gray one using gnuplot last time. Except this, Gnuplot also can do some other manipulations such as cropping, rotating and so on. In this article and next few ones I will talk about them respectively. This time we deal with cropping.

Cropping is selecting specific area from the picture, then drawing it to an output file. In gnuplot this can be done by setting the xrange and yrnage to a proper value and then plot. The script is shown below.
#Utility: crop png pictures using gnuplot.
#Author:数声风笛离亭晚,我想潇湘君想秦!
#Email:qinjieli@gmail.com
#Usage:
##call "crop.gnuplot" x1 y1 x2 y2 inputfile outputfile
#parameters:
##x1: x-value of left-bottom point
##y1: y-value of left-bottom point
##x2: x-value of right-top point
##y2: y-value of right-top point
##inputfile: input filename (without ".png")
##outputfile: output filename (without ".png")
reset
x1="$0"   #The left bottom point
y1="$1"
x2="$2"   #The right top point
y2="$3"
inputfile="$4.png"    #inputfile name
outputfile="$5.png"   #outputfile name
set xrange [x1:x2]
set yrange [y1:y2]
set size ratio -1
# Set the scales so that the unit has the same length
#on both the x and y axes
#There shold be no margin
set lmargin 0
set rmargin 0
set tmargin 0
set bmargin 0
#There shold be no key tics and border
unset key
unset tics
unset border
set term png truecolor size (x2-x1),(y2-y1)
set output outputfile
plot inputfile binary filetype=png w rgbimage
Save this script as "crop.gnuplot". Then it can be called from gnuplot like this:
gnuplot> call "crop.gnuplot" x1 y1 x2 y2 inputfile outputfile
In the end as usual let me show a finished work.

Input picture file (initial file download from here)

Picture cropped using command "call "plot.gplt" 250 150 500 400 input output"

Tuesday, September 27, 2011

Convert a rgb colorized png picture to a gray one using gnuplot

I will talk about convert a colorized rgb image to a gray one using gnuplot in this article.
Amazing it is to edit pictures with gnuplot. Yes, it is a little amazing, this kind of works should left to picture editors in fact. But I will show you gnuplot can also do it well.
In a rgb image, the color of a point is marked with (r,g,b) where r,g and b can be and always are diffrent values. While for a gray one r,g and b must be the same. So to convert a rgb image to a gray one, we should convert (r,g,b) to (gray,gray,gray). Once we known how to do it, the problem becomes easy. Now we come to write our gnuplot script.
#Utility:Convert a rgb colorized image to a gray one
#Author:数声风笛离亭晚,我想潇湘君想秦!
#Email:qinjieli@gmail.com
#Usage:
##call "rgbtogray.gnuplot" inputfile outputfile
#parameters:
##inputfile: input filename (without ".png")
##outputfile: outputfilename (without ".png")
reset
inputfile="$0.png"
outputfile="$1.png"
plot inputfile binary filetype=png w rgbimage
xmax=GPVAL_DATA_X_MAX
xmin=GPVAL_DATA_X_MIN
ymin=GPVAL_DATA_Y_MIN
ymax=GPVAL_DATA_Y_MAX
set xrange [xmin:xmax]
set yrange [ymin:ymax]
#get the size of the picture
gray(r,g,b)=0.299*r + 0.587*g + 0.114*b
#The function which convert rgb color to gray.
#At first I choose the three weighting all to be 0.333,
#but a firend told me it will be better to use these values
set size ratio -1
# Set the scales so that the unit has the same length
#on both the x and y axes
#########################
#There should not be any margin in the output picture
set lmargin 0
set rmargin 0
set tmargin 0
set bmargin 0
unset key   #The key, border and tics are all do not need
unset border
unset tics
#set terminal and output file name
set term png size (xmax-xmin),(ymax-ymin)
set output outputfile
#Plot with gray color
plot inputfile\
     u (gray(column(1),column(2),column(3))):\
       (gray(column(1),column(2),column(3))):\
       (gray(column(1),column(2),column(3)))\
     binary filetype=png w rgbimage
Save the script as "rgbtogray.gnuplot", then it can be called like this:
gnuplot> call "rgbtogray.gnuplot" inputfile outputfile
The following is two groups of our input and ouput files. The initial input files are copied from here and here (Thanks the original picture author!).
 

Input file-1

Output file-1

Input file-2

Output file-2

Saturday, September 24, 2011

Implicit function plotting using gnuplot

Assume three is an equation f(x,y)=g(x,y), and we want to plot the roots which obey this equation. This is a typical implicit function plotting problem. How do we handle this problem using gnuplot?

The most simple idea is solving the equation analytically (or numerically), and get the the root y=h(x) (or a data file containing the roots). Then plot h(x) (or the data file) with gnuplot. Of course, it is OK. But here we provide a more simpler method.

Note that the contour line at level 0 for function z=f(x,y)-g(x,y) is just the lines made up by the points which obey equation f(x,y)=g(x,y). So we can convert implicit function plotting problem to a contour plotting problem. Now come to a example.
reset
set term png enhanced lw 2 font "Times,18"
set output "implicit.png"
set contour
set cntrparam levels discrete 0
set view map
unset surface
set nokey
set isosamples 1000,1000
set xrange [-2:2]
set yrange [-2:2]
set xlabel "x"
set ylabel "y"
set title "Implicit plot of sin(x^2+y^2)=exp(-xy)"
splot sin(x**2+y**2)-exp(-x*y)
Picture implicit.png is as follows.

Implicit Plot Using Gnuplot

Thursday, September 22, 2011

Creating gif animation using gnuplot

Now the new version of gnuplot(gnuplot4.6) makes things much easier, you can refer to another of my posts for the new way.

Some times an animation makes thing much easier to be understood. When I was in middle school, I can not understand the propagation of wave well although the teacher took great effort to explain it to me. At last he show me an animation of propagating wave, at the instance i understand it. So can gnuplot create such a powerful thing? The answer is yes. Under gif terminal, if the animate option is selected, Gnuplot will thought each plot as a frame of an animation. Next is an example.
#We will plot sin(x+t) in this gif animation
reset
set term gif animate
set output "animate.gif"
n=24    #n frames
dt=2*pi/n
set xrange [0:4*pi]
i=0
load "animate.gnuplot"
set output
where file animate.gnuplot contain the following gnuplot commands:
plot sin(x+i*dt) w l lt 1 lw 1.5 title sprintf("t=%i",i)
i=i+1
if (i < n) reread
Note you can not use "plot for ..." to create an animation, because gnuplot will look it as a single plot and will only create a single frame. Run the script we get an animation as this.


Tuesday, September 20, 2011

Gnuplot I/O: Use fit command to scanf data from files

We usually record our data as follows:
x0         y0
x0+dx      y1
x0+2*dx    y2
...
In fact there is so much redundancy. For the first column we only need to record two numbers x0 and dx. So in a compact format the data can be stored as:
x0
dx
y0
y1
y2
...
Some one may say "these days the memory is so cheap, I do not care the bytes". But have you consider the speed? When you come to process the data, the larger the data file is, the longer time will your program takes. So this new format is worthy.

But problems raised when you want to plot the data file using gnuplot. The software do not recognize this new format. So the task of this article is making gnuplot understand this format.

Firstly we need to read x0 and dx out form the file. As for gnupot there is no functions like scanf in c programming language, we need to play a trick here. We use command fit to read the data out. We known that if there is only two point, the fitting result using function f(x)=a*x+b will be exact. So we use command
fit f(x) "my_format.dat" u 0:1 every ::0::1 via a,b
to fit the first two points. Then we get x0=f(0), dx=f(1). Now the xvalue can be generated by x0+$0*dx. As the xvalue has been prepared, we can come to plot the data file. Now Let me show an example. The plotting script reads:
reset
set term png font "Times,18"
set output "my_format.png"
f(x)=a*x+b
fit f(x) "my_format.dat" u 0:1 every ::0::1 via a,b
x0=f(0)
dx=f(1)
set xlabel "Time(ms)"
set ylabel "Light Intensity(Arbitary Unit)"
set mxtics 5
set mytics 2
set grid xtics mxtics ytics mytics
set offset 0,0,0.05,0
plot "my_format.dat" u (x0+$0*dx):1 every ::2 with lines linewidth 2 notitle
Data file my_format.dat can be downloaded here. And the graph is shown below.

Sunday, September 18, 2011

transparency in gnuplot

There is options to set the fill color in gnuplot to be transparent. But some friends of mine ofen complained that it never works. This is because to let the transparency really work, you also need to choose a transparency supported terminal type. For raster graphics "png" may be a choice, and for vector graphics it may be "pdf". You can use command "help transparent" to see the details.
There is an example.
reset
f(v,T)=4/sqrt(pi*T**3)*exp(-v**2/T)*v**2
set sample 500
set title "Maxwell speed distribution"
set xlabel "Speed [(2kT_c/m)^{1/2}]"
set ylabel "Probability Intensity f(v)"
set style fill transparent solid 0.5
set key Left
set term png truecolor enhanced font "Times,15"
set output "maxwell_speed_distribution.png"
plot [0:5] f(x,0.1) w filledcurves x1 title "T=0.1T_c",\
           f(x,1)   w filledcurves x1 title "T=T_c",\
           f(x,5)   w filledcurves x1 title "T=5T_c"
set term pdf enhanced
set output "maxwell_speed_distribution.pdf"
replot
Note that when transparency is used in png terminal, the "truecolor" option must be selected.

The png file is shown below and the pdf file can be downloaded here.

Saturday, September 17, 2011

Plot histograms using boxes

Some one may ask:"There is histogram plot style in gnuplot, why plot it with boxes?" I would like to say there is some restriction on the built in histogram plot style, for example the x-axis is always using the row number, you can not make it using the coloumns in the data file.

The simplest case is that there is only one group of data to be plotted. In this case you just set the boxwidth to a proper value, for example 0.95, and plot it with boxes. Here is an example.
The data file is like this:
1975    0.5     9.0
1980    2.0     12.0
1985    2.5     10.1
1990    2.6     9.1
1995    2.0     7.2
2000    5.0     8.0
2005    10.2    6.0
2010    15.1    6.2
The plotting script is like this:
reset
set term png truecolor
set output "profit.png"
set xlabel "Year"
set ylabel "Profit(Million Dollars)"
set grid
set boxwidth 0.95 relative
set style fill transparent solid 0.5 noborder
plot "profit.dat" u 1:2 w boxes lc rgb"green" notitle
This example plot a graph like this one:

Plot histogram using boxes with one group of data

When there is more than one group of data to plot, the boxwidth and gap between the boxes should be calculated carefully. We do it like this:
reset
dx=5.
n=2
total_box_width_relative=0.75
gap_width_relative=0.1
d_width=(gap_width_relative+total_box_width_relative)*dx/2.
reset
set term png truecolor
set output "profit.png"
set xlabel "Year"
set ylabel "Profit(Million Dollars)"
set grid
set boxwidth total_box_width_relative/n relative
set style fill transparent solid 0.5 noborder
plot "profit.dat" u 1:2 w boxes lc rgb"green" notitle,\
     "profit.dat" u ($1+d_width):3 w boxes lc rgb"red" notitle
This time we get a histogram with two group of data like this:

Plot histogram using boxes with more than one group of data

Friday, September 16, 2011

Statistic analysis using gnuplot (1)

Last time we dealt with the maximum, minimum and mean value of a statistic analysis problem. Today the standard deviation will be added.
The standard deviation is defined as the square root of the variance. With variance stand for the mean squared value minus the squared mean value. The mean value have been dealt last time. We just need to store it. Strange it is, although there is only one data point after the smooth, when I plot it to a data file using the table mode, I get two output points with the second one marked with "u" which means undefined value.(who can tell me why?) In a similar way we plot the mean of squared value to another data file. Next we read this two value out from the data file. And use them to calculate the standard deviation. Since there is only two data points in the file, we use f(x)=ax+b to fit the data, and the fitted result will be exact, then we can use f(x) to get these exact values. At last we plot the standard deviation on the graph. The following is our final plotting script.
reset
plot "rand_t.dat" u 1:2	#To get the max and min value
ymax=GPVAL_DATA_Y_MAX
ymin=GPVAL_DATA_Y_MIN
ylen=ymax-ymin
xmax=GPVAL_DATA_X_MAX
xmin=GPVAL_DATA_X_MIN
xlen=xmax-xmin
set table "mean.txt"	#put the mean value out
plot "rand_t.dat" u ((xmax+xmin)/2.0):($2) smooth unique w p
unset table
set table "mean_squared.txt"	#put the mean of squared value out
plot "rand_t.dat" u ((xmax+xmin)/2.0):($2**2) smooth unique w p
unset table
f(x)=a*x+b	#The fit functions
g(x)=c*x+d
fit f(x) "mean.txt" u 0:2 via a,b	#Read the mean and mean of squared value
fit g(x) "mean_squared.txt" u 0:2 via c,d
mean=f(0)	#mean value
mean_squared=g(0)	#mean of the squared value
standard_deviation=sqrt(mean_squared-mean**2)	#standard deviation
print "The mean value is ",mean		#print the mean and standard deviation
print "The standard deviation is ",standard_deviation
#plot
set term post eps enhanced color lw 1.5 font ",20"
set output "statistic.eps"
set xrange [xmin:xmax]
set yrange [ymin-0.5*ylen:ymax+0.5*ylen]
set xlabel "time"
set ylabel "Random Signal"
#The labels
set label 1 at (xmin+xmax)/2.,ymax "Maximum" offset 0,0.5
set label 2 at (xmin+xmax)/2.,ymin "Minimum" offset 0,-0.5
set label 3 at (xmin+xmax)/2.,mean "Mean" offset 0,0.5
set label 4 at (xmin+xmax)/2.,mean+3*standard_deviation \
             "Mean+3{/Symbol \163}" offset 0,0.5
set label 5 at (xmin+xmax)/2.,mean-3*standard_deviation \
             "Mean-3{/Symbol \163}" offset 0,-0.5
plot "rand_t.dat" u 1:2 w p pt 7 ps 0.5 notitle,\
     mean w l lt 2 notitle "Mean",\
     ymax w l lt 3 notitle "Maximum",\
     ymin w l lt 3 notitle,\
     mean+3*standard_deviation w l lt 4 notitle,\
     mean-3*standard_deviation w l lt 4 notitle
#the six plot stand for raw data, mean, maximum, minimum,
#3-sigma upper line and 3-sigma lower line
At last we get figure like follows.

Statistic analysis using gnuplot

Wednesday, September 14, 2011

Statistic analysis using gnuplot (0)

I will talk about statistic analysis using gnuplot in this article. The following contents are covered---maximum, minimum, mean value, standard deviation.

We begin with the maximum and minimum as they are the simplest. There are two gnuplot defined variables (to see all the gnuplot variables use command "show variable all"), GPVAL_DATA_Y_MAX and GPVAL_DATA_Y_MIN. They are the maximum and minmum y value in the data file which you just used to plot. So after plotting you look over the gnuplot defined variables and you find the maximum and minimum values.

The mean value is a bit difficult. There is no such a gnuplot defined value. To find it out we will play a trick. There is smooth option called "unique" which makes the data monotonic in x and points with the same x-value are replaced by a single point having the average y-value. So it is appropriate for finding the mean value. We use command
plot "data_t.dat" u (constant-value):($n) smooth unique w point
to plot the mean value. Here constant-value is an arbitrary constant and $n is the column which contains the random data. Note that there is only one point plotted using the above command, so plot style line can not be used. To plot the the mean value using a line we may need to use xerrobars plot style. (Next time I will give a method to plot it using plot style line.)
plot "data_t.dat" u (constant-value):($n):(xerrobar-length) smooth unique w xerrorbars

Now we come to plot the data points, maximum, minimum and mean value to a picture. And standard deviation is left next time.
reset
plot "rand_t.dat" u 1:2	#To get the max and min value
ymax=GPVAL_DATA_Y_MAX
ymin=GPVAL_DATA_Y_MIN
ylen=ymax-ymin
xmax=GPVAL_DATA_X_MAX
xmin=GPVAL_DATA_X_MIN
xlen=xmax-xmin
#plot
set term png
set output "statistic.png"
set xrange [xmin:xmax]
set yrange [ymin-0.5*ylen:ymax+0.5*ylen]
set xlabel "time(ms)"
set ylabel "Random Signal(Arbitary Unit)"
plot "rand_t.dat" u 1:2 w p pt 7 ps 0.5 notitle,\
     "rand_t.dat" u (xmax+0.1*xlen):($2):(1.1*xlen)\
     smooth unique w xerrorbars notitle,\
     ymax w l lt 3 notitle,\
     ymin w l lt 3 notitle
#plot raw data, mean value, maximun and minimun respectively
#There is only one data point for the mean value. To make it 
#looks like a line, we plot it using a xerrorbars plot style.
rand_t.dat can be downloaded here. Picture statistic.png is shown below.
Statistic analysis using gnuplot--maximum,minimum and mean value

Sunday, September 11, 2011

Statistic analysis and histogram plotting using gnuplot

Given a data file containing a set of data, count how many datas locate in intervals [a1:a2],[a2:a3]... respectively, then plot the result into a histogram. This a common problem in statistics and exactly what we will do in this article.

Firstly, let us see how to map the data into intervals. There is a function "floor(x)" which return the largest integer not greater than its argument. So function floor(x/dx)*dx will map x into one of the intervals [-n*dx:-(n-1)*dx],[-(n-1)*dx:-(n-2)*dx]...[(n-1)*dx:n*dx].

Now we come to count the data number in each interval. In gnuplot there is a smooth option called "frequency". It makes the data monotonic in x. Points with the same x-value are replaced by a single point having the summed y-values. Using this property, we can count the data numbers in the intervals.

At last we plot our result using boxes plot style.

The main idea have introduced. It is time to write the plotting script.
reset
n=100 #number of intervals
max=3. #max value
min=-3. #min value
width=(max-min)/n #interval width
#function used to map a value to the intervals
hist(x,width)=width*floor(x/width)+width/2.0
set term png #output terminal and file
set output "histogram.png"
set xrange [min:max]
set yrange [0:]
#to put an empty boundary around the
#data inside an autoscaled graph.
set offset graph 0.05,0.05,0.05,0.0
set xtics min,(max-min)/5,max
set boxwidth width*0.9
set style fill solid 0.5 #fillstyle
set tics out nomirror
set xlabel "x"
set ylabel "Frequency"
#count and plot
plot "data.dat" u (hist($1,width)):(1.0) smooth freq w boxes lc rgb"green" notitle
We use a data file (download from here) which contains 10000 normally distributed random numbers and get a graph like the follow one.

statistic histogram plotting using gnuplot

Friday, September 9, 2011

Manipulate data using ternary operator in gunplot

In gnuplot there is an operator "? :" which is ternary. It behaves as it does in C language. For example, "a?b:c" means if a is true then return 'b', otherwise return 'c'. Using this operator we can do some complex operation on input data. Let us see an example.

We have a data file as follows:
#x  y1   y2
0.1	0.2	0.2
0.2	0.4	0.4
0.3	0.6	0.6
0.4	0.8	0.8
0.5	1	1
0.6	1.2	1.2
0.7	1.4	1.4
0.8	2.4	0.6
0.9	2.7	0.675
1	3	0.75
1.1	3.3	0.825
1.2	3.6	0.9
1.3	3.9	0.975
1.4	4.2	1.05
1.5	4.5	1.125
We want to plot the points y1=y2 with blue pints, and other points y1!=y2 (y1 not equals y2) with some other colors. To realize this goal, we can use ternary operator. According to the definition of ternary operator, expression "$2==$3?$2:1/0" will return the points satisfy $2=$3, and when $2!=$3 it returns undefied value(1/0 is an undefied value). So when we use command "plot 'data.dat' u 1:($2==$3?$2:1/0) w p", we plot the points with y1=y2. In a simillar manner, we can plot the points with y1!=y2. Now we come to our final plotting script.
reset
set term png font "Times,20"
set output "ternaty.png"
set xlabel "x"
set ylabel "y"
plot "data.dat" u 1:($2==$3?$2:1/0) w p lc rgb"blue" notitle,\
     "data.dat" u 1:($2!=$3?$2:1/0) w p lc rgb"green" notitle,\
     "data.dat" u 1:($2!=$3?$3:1/0) w p lc rgb"red" notitle
The picture comes out to be like follows.

Manipulate data using ternary operator in gnuplot

Gradient colored curve in Gnuplot(2)

In the previous article we plot a gradient colored curve by expanding it to a 3-d surface and view the surface in a particular viewpoint. Today we talk about a third method.

In gnuplot we can specify the plotting colors by "rgbcolor variable". It can assign a separate color for each data point,line segment,or label based on additional information in the input data file. For example "plot 'data.dat' u 1:2:3 with points lc rgb variable" will plot each data point with separate color according to the third column of the data file. Now we come to plot the following data file using "rgbcolor variable".
0.0 	0.00 
0.2 	0.14 
0.4 	0.56 
0.6 	1.25 
0.8 	2.12 
1.0 	3.00 
1.2 	3.65 
1.4 	3.90 
1.6 	3.79 
1.8 	3.64 
2.0 	4.00 
2.2 	5.40 
2.4 	8.10 
2.6 	11.84 
2.8 	15.84 
3.0 	19.00 
3.2 	20.41 
3.4 	19.78 
3.6 	17.78 
3.8 	15.91 
4.0 	16.00 
4.2 	19.42 
4.4 	26.39 
4.6 	35.66 
4.8 	44.78 
5.0 	51.00 
5.2 	52.40 
5.4 	48.90 
5.6 	42.54 
5.8 	36.95 
6.0 	36.00 
6.2 	42.21 
6.4 	55.46 
6.6 	72.72 
6.8 	88.97 
7.0 	99.00 
7.2 	99.63 
7.4 	91.26 
7.6 	78.06 
7.8 	66.75 
8.0 	64.00 
8.2 	73.76 
8.4 	95.28 
8.6 	123.02 
8.8 	148.39 
9.0 	163.00 
9.2 	162.10 
9.4 	146.85 
9.6 	124.35 
9.8 	105.31 
Our plotting script is:
reset
plot "data.dat" #To get the max and min vaule
MAX=GPVAL_Y_MAX
MIN=GPVAL_Y_MIN
LEN=MAX-MIN
set term png
set output "gradient_colored_curve3.png"
set key off
plot "data.dat" w l lw 2 lc rgb"green" smooth csplines, \
     "data.dat" u 1:2:(255-($2-MIN)/LEN*255) w p pt 7 \
     ps 2 lc rgb variable notitle
#(255-($2-MIN)/LEN*255) means when data vary from min
#to max, color vary from blue to black
It is a simple and good method. But it is hard for us to design a beautiful color palette. This is its disadvantage.

At last is what does the picture gradient_colored_curve3.png looks like.

Gradient colored curve plotted by gnuplot

Gradient colored curve in Gnuplot(1)

Last time we talked about how to draw a gradient colored curve. We realized it by cutting the total curve into n segment and plot the n segment using different colors. This time we talk about another method.

We know that at a special viewpoint a surface can appear like a line. We also know that gunplot can plot colored surface with pm3d plotting style. So we may expand our line to a surface. Plot the surface with pm3d. View it in a special viewpoint. Now we come to realize our idea.
reset
set term png
set output "gradient_colored_curve2.png"
set isosample 200,2 
#As along y-axis the surface has a constant value,
#the samples along y-axis can set to be a small value.
set palette rgbformulae 7,5,15
unset colorbox
set xyplane relative 0
set xtics offset 0,-1   
#putting xtics label 1 character lower makes the plotting nicer
unset ytics #ytics is not necessary
unset border #the border will plot manually
#plot axes manually
set arrow 1 from graph 0,0,0 to graph 1.1,0,0
set arrow 2 from graph 0,0,0 to graph 0,0,1.1
#plot xtics manually
set for [i=-10:10:5] arrow from i,0,-1.0 to i,0,-0.95 nohead
set view 89.5,0 #map the 3-d surface to coordinate plane
splot sin(x) w pm3d notitle
Note that the view should be set to a value near "90,0" but not exactly "90,0" (if view exactly equals "90,0", "linwidth" of the curve is 0), here we choose "89.5,0". Compared to the previous one, this method takes less time. The output picture file is shown below.

Gradient colored curve plotted by gnuplot

Wednesday, September 7, 2011

Gradient colored curve in Gnuplot(0)

A friend of mine asked me:"How can we plot a figure like this one (the following one) using gnuplot?"

Gradient colored curve

It is a bit hard. We know that command
plot function-or-datafile with lines linecolor rgb"rgb-color"
can plot a curve with specific color, but the color can not vary along the curve. How to deal with this kind of picture? I thought for a while and answered:"I have three different methods. Let me tell you one by one, and you can select the one which you like most."

Today I will introduce my first method.

The idea is simply cutting the curve into n segments, and plot these n sub-curves with different colors. It is realized by the following gnuplot script.
reset
set term png
set output "gradient_colored_curve1.png"
f(x)=exp(-0.33*x)*sin(5*pi*x)   #The function to be plotted
n=100   #divide the whole curve into n segments
set samples 300 #must be large enough for each segment have at least 2 samples
set palette rgbformulae 30,13,10    #rainbow palette
set cbrange [0:n]
set xrange [0:10]
unset colorbox  #The colorbox will not plotted
#Plot the n segments of the curve
plot for [i=0:n] i<=x*n/10 && x*n/10<(i+1.5) ?f(x):1/0 \
     w l lw 2 lc palette cb i notitle
In the script it is "i+1.5" not "i+1", because we want two segments close to each other have a common part. In such a way the boundary between them will not so obvious. And be sure that the samples should be set to a value large enough for each small segment have at least 2 samples. The advantage of this method is its simplicity. The disadvantage is that since this script will plot for n times, it will take a very long time (on my computer about 1 second). This script just produce a picture the same as the one my friend shown me.

Sunday, September 4, 2011

Shadow to the key in Gnuplot

Yesterday we talk about shadow to a curve in gnuplot . But the key is not plotted. Now we come to add a shadowed key to our graph. The method is the same as before, plotting the objects two or more times. The following is an example gnuplot script.
reset
set term png
set output "shadowkey.png"
dy=0.75
angle=pi/6.0
dx=dy*tan(angle)
f(x)=0.1*(x-10)*x*(x+10)
set object 1 rectangle from graph 0.91,0.89 \
    to graph 0.66,0.74 fillstyle solid 1.0 noborder \
    fc rgb"#cccccc"	#key-box shadow
set object 2 rectangle from graph 0.9,0.9 \
    to graph 0.65,0.75 fc rgb"#ffffff"    #key-box
set arrow 1 lw 7 lc rgb"#cccccc" from graph 0.78,0.82 \
    to graph 0.86,0.82 nohead #samle-line shadow
set arrow 2 lw 7 lc rgb"red" from graph 0.77,0.83 \
    to graph 0.85,0.83 nohead     #sample-line
set label 1 "f(x)" at graph 0.7,0.83	#key label
set xrange [-15:15]
plot f(x-dx)-dy w l lw 7 lc rgb"#cccccc" notitle,\
     f(x) w l lw 7 lc rgb"red" notitle
Because gnuplot can not give us enough control on the key by using command "set key ...", in this script we draw the key manually using rectangles,arrows and label. The final appearance of shadow1.png is shown below.

Shadow to the key in gnuplot

Saturday, September 3, 2011

Shadow to a curve in Gnuplot

Adding shadow to a curve or some other objects can makes a 2-d plot looks like a 3-d one. The common way producing a shadow effect is drawing the object two times. Now let us come to an example of shadowing to a curve.
reset
set term png
set output "shadow1.png"
dy=0.75
dx=dy*tan(pi/6)
f(x)=0.1*(x-10)*x*(x+10)
set xrange [-15:15]
plot f(x-dx)-dy w l lw 7 lc rgb"#cccccc" notitle,\
      f(x) w l lw 7 lc rgb"red" notitle
Simple shadow effect
Firstly the shadow offset along y-axis and x-axis are given. The earlier plot is used to produce the shadow effcet and the later one is the data plotting. Note that the data plotting must be put after the shadow plotting, otherwise the "shadow" may cloud the data-curve. From the picture we find that the shadow effect have been realized, but it seems that the shadow is too sharp. We need to improve the script to get a better effect. Now let us do this. Our main idea is plotting the shadow sevral times with diffrent scale of gray colors. We realize this idea using a "for" iteration. The following is our improved script and the corresponding graph.
reset
set term png
set output "shadow2.png"
dy=0.75
dx=dy*tan(pi/6)
levels=15
f(x)=0.1*(x-10)*x*(x+10)
set palette gray
set cbrange [0:1]
unset colorbox
set xrange [-15:15]
set yrange [-200:200]
set multiplot
plot for [i=levels:1:-1] f(x-i*(1.0/levels)*dx)-i*(1.0/levels)*dy w l lw 7 \
      lc palette cb i*(0.5/levels)+0.35 notitle
plot f(x) w l lw 7 lc rgb"red" notitle
unset multiplot
Improved shadow effect

Friday, September 2, 2011

Gnuplot background image

Gnuplot can read png binary file and then plot it on the canvas. Using this utility we can add a background image to our plot. Let us see an example script.
reset
set term png
set output "world_population.png"
set multiplot
set xrange [0:799] 
set yrange [0:409]
#As the background picture's size is 800x410,
#we choose xrange and yrange of these values
unset tics
unset border
set lmargin at screen 0.175
set rmargin at screen 0.9
set bmargin at screen 0.15
set tmargin at screen 0.9
#Plot the background image
plot "map.png" binary filetype=png w rgbimage
#The x and y range of the population data file
set xrange [1740:2020]
set yrange [0:7000]
set border
set tics out nomirror scale 2
set mxtics 5
set key left
set xlabel "Year"
set ylabel "Population(in millions)"
plot "population.dat" u 1:2 w lp lw 2 ps 1 pt 7 title "world",\
     "population.dat" u 1:3 w lp lw 2 ps 1 pt 7 title "Africa",\
     "population.dat" u 1:4 w lp lw 2 ps 1 pt 7 title "Asia",\
     "population.dat" u 1:5 w lp lw 2 ps 1 pt 7 title "Europe",\
     "population.dat" u 1:6 w lp lw 2 ps 1 pt 7 title "Katub America",\
     "population.dat" u 1:7 w lp lw 2 ps 1 pt 7 title "Northern America",\
     "population.dat" u 1:8 w lp lw 2 ps 1 pt 7 title "Oceania"
unset multiplot
In this script, map.png is our background image with size 800x410 (That is why we choose xrange and yrange to be 0-799 and 0-409 respectively). population.dat is a file containing information of world population from 0 AD to 2000 AD. The first plot command is used to plot the background image, while the second plot command is used to plot our world population data file. To make these two plot coincide with each other, l,r,t,bmargin are set in the screen coordinate. The data file is as follows:
#Data from http://en.wikipedia.org/wiki/World_population
#Year  World  Africa  Asia  Europe  Latin America  Northern America  Oceania
1750  791  106  502  163  16  2  2  
1800  978  107  635  203  24  7  2  
1850  1262  111  809  276  38  26  2  
1900  1650  133  947  408  74  82  6  
1950  2519  221  1398  547  167  172  12.8  
1955  2756  247  1542  575  191  187  14.3  
1960  2982  277  1674  601  209  204  15.9  
1965  3335  314  1899  634  250  219  17.6  
1970  3692  357  2143  656  285  232  19.4  
1975  4068  408  2397  675  322  243  21.5  
1980  4435  470  2632  692  361  256  22.8  
1985  4831  542  2887  706  401  269  24.7  
1990  5263  622  3168  721  441  283  26.7  
1995  5674  707  3430  727  481  299  28.9  
2000  6070  796  3680  728  520  316  31.0  
2005  6454  888  3917  725  558  332  32.9  
2008  6707  973  4054  732  577  337  34.3
To use background image file of format other than png, we shold first convert it to a png file. This task can be done well using ImageMagick.

At last, this is the picture file world_population.png produced by the plotting script.

Gnuplot background image

Thursday, September 1, 2011

Gnuplot advanced background color (1)

An alternative way to realize a linear gradient colored background is using the image plotting style. Let us first look at our final script and then explain it.
reset
set table "back.dat"	#creat a data file
set isosample 2,200	#containing linear
splot y			#gradient color 
unset table		#information

splot y	#Get the max value of z
max=GPVAL_Z_MAX

set term png
set output "backgradient2.png"
set multiplot
#plot the background
set lmargin at screen 0
set rmargin at screen 1
set bmargin at screen 0
set tmargin at screen 1
unset border
unset tics
set palette defined(0"white",max"#ccffcc")  #set gradient color
plot "back.dat" w ima
#plot the curve of sin(x)
set border 1+2+4+8
set tics
set lmargin
set rmargin
set bmargin
set tmargin
plot sin(x) w l lw 2 lc rgb"black" notitle
unset multiplot
!del back.dat
#in unix system the above command may should be change to "!rm back.dat"
In this script, firstly we produce a date file "back.dat" which contain linear gradient color information. Then in a multiplot environment we plot the background using command '''plot "back.dat" w ima''' and figure of sin(x) using '''plot sin(x) w l lw 2 lc rgb"black" notitle'''. Before plotting the background we set l,r,b,tmargin to be 0,1,0,1 respectively, thus the background is filled the whole picture, and border and tics are unset. After that all of border,margins and tics are set again. "! del back.dat" is used to delete temporary data file back.dat. backgradient2.png is show below:

Linear gradient colored background
 
Creative Commons License
Except as otherwise noted, the content of this page is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.