Hey guys I am currently working with gnuplot.
I have this .csv file which I have been using to plot some formulas
(eg plot "filename.csv" u 0:day($0) = $0 ). The plots worked out; however, I was wondering if there was a way within gnuplot to save the output of my formulas as a data file too.
Please check the manual or in the gnuplot console type help table.
Code:
### save data as text
reset session
f(x) = x
g(x) = x**2
h(x) = x**3
set xrange[-5:5]
set samples 11
plot f(x) w lp, g(x) w lp, h(x) w lp
set table "myOutput.dat"
plot '+' u 1:(f($1)):(g($1)):(h($1)) w table
unset table
### end of code
Edit:
Actually, to be more flexible with data separators (e.g. comma or whatever) in the output file, you could change the plot ... w table command to something like the line below. However, I guess, gnuplot will always add a leading space " " and a trailing TAB \t for each line. But maybe this can also be changed.
plot '+' u (sprintf("%g,%g,%g,%g",$1,f($1),g($1),h($1))) w table
Result:
And myOutput.dat:
-5 -5 25 -125
-4 -4 16 -64
-3 -3 9 -27
-2 -2 4 -8
-1 -1 1 -1
0 0 0 0
1 1 1 1
2 2 4 8
3 3 9 27
4 4 16 64
5 5 25 125
Addition: (creating data in a loop)
With set print you are probably the most flexible, no leading space and trailing TAB.
Check the manual or in gnuplot console type help set print.
Code:
### save data as text, independent of range and samples
reset session
f(x) = x
g(x) = x**2
h(x) = x**3
set print "myOutput.dat"
do for [i=-5:5] {
# loop index only takes integers, multiply i with some factor if necessary
print sprintf("%g,%g,%g,%g",i,f(i),g(i),h(i))
}
set print
### end of code
Related
I have data that have 3 points to display in a 3D coordinate system. I want a line between each point and the coordinate origin (0 0 0). How can I draw these lines not connecting the points with each other but only with the origin?
I'm not very into gnuplot yet: I'm using the following code to display my data:
splot "C:/a/Drehmatrizenxyz.txt" with lines
But this only connects the points, which is exactly what I do not want.
Thank you.
Data file contains six values for each line. From origin is (0 0 0 x y z)
Example - plot vectors <-1,2,-4>, <-2,0,1> & <2,9,2>
file.dat:
0 0 0 -1 2 -4
0 0 0 -2 0 1
0 0 0 2 9 2
gnuplot> splot 'file.dat' with vectors
vectors
In case this is still of interest...
Please check the gnuplot homepage and basic gnuplot tutorials and in gnuplot console help vectors or in general help <keyword>.
Code:
### plot with vectors from origin
reset session
$Data <<EOD
1 2 3
4 5 6
7 8 1
EOD
set view equal xyz
set view 56,48, 1.3
set xyplane relative 0
splot $Data u (0):(0):(0):1:2:3 w vectors
### end of code
Result:
I have a file that I need to plot in a graph that looks similar to this:
gnuplot sample graph
Here is my file that I am trying to plot:
441.81 823.36 192765 3044.68 4242.61
X 2609.3 4901.96 8306.6 12058.18
1632.27 4098.15 9299.14 16295.19 24665.59
I can do a simple plot, but changing the line types and using a file is what I am having trouble with. I'm not sure how to get the data from the file into the plot and make it formatted like the sample image.
You probably should dig a little deeper into gnuplot. A good start is this article on plotting data.
Anyway, let's define three distinct line styles:
set style line 1 lc 'blue' lt 1 lw 2 pt 6 ps 1.5
set style line 2 lc 'red' lt 1 lw 2 pt 6 ps 1.5
set style line 3 lc 'green' lt 1 lw 2 pt 6 ps 1.5
Then, we can call the plot function on our inputFile:
plot 'inptFile' u 1:2 w lp ls 1, '' u 1:3 w lp ls 2, '' u 1:4 w lp ls 3
(u 1:2 stands for using 1:2 and means that we use the value in the first column as x-coordinate and the value in the second column as the y-coordinate. )
Note that our inputFile looks like this (i.e., each line contains a point's x and y-coordinate):
-1 2 3 4
0 1 2 4
1 2 4 16
2 3 16 8
Output:
I'm using this minimal sample:
set xrange [0:10]
plot x**2
This produces a nice smooth graph. However, I'd like that there are only points plotted on natural values for x (0, 1, 2, ..., 10), making the chart 'rigid', something like this:
Is there a possibility to do this without a data file?
I know about Gnuplot x-axis resolution, however, if I would use that, I would need to tweak the sample resolution every time I change the xrange.
using shell
Instead of a file, you can pipe a shell command to give you the points you want :
plot "<seq 0 10" using 1:($1**2) w lp
portability ?
See this documentation : http://www.chemie.fu-berlin.de/chemnet/use/info/gnuplot/gnuplot_13.html#SEC53, I quote :
On some computer systems with a popen function (UNIX), the datafile can be piped through a shell command by starting the file name with a '<'.
Apparently this also works on some windows systems (with cygwin), though other windows platform fail with a miserable error (see below). This seems to be in that case because gnuplot opens a windows batch shell.
If however you try to call a shell command through the system("command") way, you get a more explicit error (at least on my windows) :
gnuplot> plot "<echo 0 1 2 3 4 5 6 7 8 9 10" using 1:($1**2) w lp \
# fails, implying the < syntax doesn't even exist
warning: Skipping unreadable file "<echo 0 1 2 3 4 5 6 7 8 9 10"
No data in plot
gnuplot> plot system("echo 0 1 2 3 4 5 6 7 8 9 10") using 1:($1**2) w lp \
# fails with proper warning, then tries to reuse previous file
warning: system() requires support for pipes
warning: Skipping unreadable file "<echo 0 1 2 3 4 5 6 7 8 9 10"
No data in plot
gnuplot> !pause # shows a windows batch window
If you want points, you can use the pseudo-file "+". It is like a file containing a series of numbers in a single column. You have to set the xrange. The number of points is determined by set samples :
set xrange[-5:5]
set samples 11 # need 11 points: 0, 1, 2, ..., 10
plot "+" u 1:($1**2) with linespoints
EDIT:
First, it is true: you do not have to use '+' just for linespoints...
OK, what's about this:
plot '+' u (floor($1)):(floor($1)**2) smooth unique w lp
Still using the pseudo-file '+', it rounds down its values to the next integer. As log ans you ensure that the number of sample points is high enough that there's alway one number generated beween each integer (let's say twice the full yrange), it works. The smooth unique prevents multible points at the same coordinates.
Using a platform-dependent system command as in #Cimbali's solution for such a task wouldn't be my perferred solution.
Here is a gnuplot-only solution where you don't have to worry about portability.
The OP doesn't want to tweak the sampling when the xrange changes, but if you want to change the xrange you have to change your script at some point in any case.
So, simply use variables for the xrange and let gnuplot do the "tweaking" of the sampling which is fairly easy since you want only natural (or integer) numbers. Assumption is that xmin is an integer as well, if not, you could use ceil() for the samples and in the plotting command.
Script: (works with gnuplot>=4.4.0, March 2010)
### plot function only for integer numbers
reset
set xrange[xmin=0:xmax=10]
set samples (xmax-xmin)+1
plot '+' u 1:($1**2) w lp pt 7
### end of script
Result:
I have a data in file which I would like to plot using gnuplot. In the file, there are 3 data sets separated by two blank lines so that gnuplot can differentiate between the data sets by 'index'. I can plot three data sets separately via 'index' option of 'plot' command.
However, I am not sure how can I plot the data which is sum of 2nd column of all three data sets?
Note: all three data sets have same x data, i.e. 1st column
To do this the simplest thing would be to change your file format. Gnuplot manipulates columns pretty well. Since you are sharing the x data, you can change the file format to have four columns (assuming you are just plotting (x,y) data):
<x data> <y1 data> <y2 data> <y3 data>
and use a command like
plot 'data.dat' using 1:2 title 'data 1', \
'' u 1:3 t 'data 2', \
'' u 1:4 t 'data 3', \
'' u 1:($2+$3+$4) t 'sum of datas'
The dollar signs inside the parens in the using column specification allow you to add/subtract/perform other functions on columnar data.
This way your data file will also be smaller since you won't repeat the x data.
#Youjun Hu, never say that there is "no way" to do something with gnuplot. Most of the cases there is a way with gnuplot only, sometimes maybe not obvious or sometimes a bit cumbersome.
Data: SO16861334.dat
1 11
2 12
3 13
4 14
1 21
2 22
3 23
4 24
1 31
2 32
3 33
4 34
Code 1: (works with gnuplot 4.6.0, needs some adaptions for >=4.6.5)
In gnuplot 4.6.0 (version at the time of OP's question) there were no datablocks and no plot ... with table. The example below only works for 3 subdatasets, but could be adapted for other numbers. However, arbitrary large number of subdatasets will be difficult with this approach.
### calculate sum from 3 different (sub)datasets, gnuplot 4.6.0
reset
FILE = "SO16861334.dat"
stats FILE u 0 nooutput
N = int(STATS_records/STATS_blocks) # get number of lines per subblock
set table FILE."2"
plot FILE u 1:2
set table FILE."3"
x1=x2=y1=y2=NaN
myValueX(col) = (x0=x1,x1=x2,x2=column(col), r=int($0-2)/N, r<1 ? x0 : r<2 ? x1 : x2)
myValueY(col) = (y0=y1,y1=y2,y2=column(col), r<1 ? y0 : r<2 ? y1 : y2)
plot FILE."2" u (myValueX(1)):(myValueY(2))
unset table
set key top left
set offset graph 0.1, graph 0.1, graph 0.2, graph 0.1
plot for [i=0:2] FILE u 1:2 index i w lp pt 7 lc i+1 ti sprintf("index %d",i), \
FILE."3" u 1:2 every ::2 smooth freq w lp pt 7 lc rgb "magenta" ti "sum"
### end of code
Code 2: (works with gnuplot>=5.0.0)
This code works with arbitrary number of subdatasets.
### calculate sum from 3 different (sub)datasets, gnuplot>=5.0.0
reset
FILE = "SO16861334.dat"
set table $Data2
plot FILE u 1:2 w table
unset table
set key top left
set offset graph 0.1, graph 0.1, graph 0.2, graph 0.1
set colorsequence classic
plot for [i=0:2] FILE u 1:2 index i w lp pt 7 lc i+1 ti sprintf("index %d",i), \
$Data2 u 1:2 smooth freq w lp pt 7 lc rgb "magenta" ti "sum"
### end of code
Result: (same result for Code1 with gnuplot 4.6.0 and Code2 for gnuplot 5.0.0)
I am trying to use R to make an excel kind of a line plot, where my x axis is text (A,B,c..etc) and the y axis(which can be both negative and positive) are up and down columns. I want to give up a red color and down green.
I would really appreciate if anyone can help me regarding this. I have plotted this in excel but i have thousands of rows in my data and excel doesnot show all the text point in my plot.
My data looks like the following:
Name UP Downs
A 10 -3
B 2 -4
C 1 -1
D 4 -1
E 5 0
F 0 -1
G 6 -5
H 0 -1
I 7 -1
J 0 -1
K 0 -11
L 3 -1
M 0 -13
N 2 -1
O 0 -1
P 1 -1
Q 0 0
R 1 -1
S 0 0
T 12 -1
This is probably not the most elegant way to do it, but you can work it all out using with plot, points, and axis (axis is the main one, it explains how you can change the labels on the axis): ?axis, ?plot, ?points.
First make a data frame similar to yours so I can demonstrate...
# make a data frame similar to yours
mydf <- data.frame( Name=LETTERS,
Up=sample.int(15,size=26,replace=T),
Down=-sample.int(15,size=26,replace=T) )
Now plot.
# set up a plot: x axis goes from 1 to 26,
# y limit goes from -15 to 15 (picked manually, you can work yours out
# programmatically)
# Disable plotting of axes (axes=FALSE)
# Put in some x and y labels and a plot title (see ?plot...)
plot(0,xlim=c(1,26),ylim=c(-15,15),type='n',
axes=FALSE, # don't draw axis -- we'll put it in later.
xlab='Name',ylab='Change', # x and y labels
main='Ups and Downs') #,frame.plot=T -- try if you like. ?plot.default
# Plot the 'Up' column in green (see ?points)
points(Up~Name,mydf,col='green')
# Plot the 'Down' column in red
points(Down~Name,mydf,col='red')
# ***Draw the x axis, with labels being A-Z
# (type in 'LETTERS' to the prompt to see what they are)
# see also ?axis
axis(1,at=1:26,labels=LETTERS)
# Draw the y axis
axis(2)
Tweak it as you wish: ?points and ?par and ?axis are particularly helpful in this respect.