I want a radial(polar) plot using gnuplot (i.e in circular co-ordinate system(r,theta).
Here I have used the values:
Theta Max-strain
0 3400
60 5300
120 4700
180 3800
240 4100
300 3100
360 3400
How to get such a plot using gnu-plot?
I tried to recreate the plot of your question and this is what I came up with:
unset border
set polar
set angles degrees #set gnuplot on degrees instead of radians
set style line 10 lt 1 lc 0 lw 0.3 #redefine a new line style for the grid
set grid polar 60 #set the grid to be displayed every 60 degrees
set grid ls 10
set xrange [-6000:6000] #make gnuplot to go until 6000
set yrange [-6000:6000]
set xtics axis #disply the xtics on the axis instead of on the border
set ytics axis
set xtics scale 0 #"remove" the tics so that only the y tics are displayed
set xtics ("" 1000, "" 2000, "" 3000, "" 4000, "" 5000, "" 6000) #set the xtics only go from 0 to 6000 with increment of1000 but do not display anything. This has to be done otherwise the grid will not be displayed correctly.
set ytics 0, 1000, 6000 #make the ytics go from the center (0) to 6000 with incrment of 1000
set size square
set key lmargin
set_label(x, text) = sprintf("set label '%s' at (6500*cos(%f)), (6500*sin(%f)) center", text, x, x) #this places a label on the outside
#here all labels are created
eval set_label(0, "0")
eval set_label(60, "60")
eval set_label(120, "120")
eval set_label(180, "180")
eval set_label(240, "240")
eval set_label(300, "300")
set style line 11 lt 1 lw 2 pt 2 ps 2 #set the line style for the plot
#and finally the plot
plot "-" u 1:2 t "Max strain" w lp ls 11
0 3400
60 5300
120 4700
180 3800
240 4100
300 3100
360 3400
e
As you can see, the major difference is that the angle 0 is not on top but on the right (which is mathematically correct). You can change this however by modifying the using deceleration in the plot and the set_label function.
As you can see in the script not everything is really crisp and shiny. If someone finds improvements please let me know!
One last bit of "advice": It is not always reasonable to try to reproduce a plot from some tool with gnuplot. Often the strength of gnuplot is to plot data in the most simple way to be easily reproducible. Maybe you can kick some lines out of that script above and still be happy with it.
Here is a manual http://t16web.lanl.gov/Kawano/gnuplot/polar-e.html
set polar
set angles degrees
and to get circles:
set grid polar
Here is a demo: http://gnuplot.sourceforge.net/demo/polar.html
Related
I have a problem. Im trying to do a polar plot, the fact it's that i want to plot some theorical line as some experimental data in the plot. But the theorical line has a range different of the experimental data because i had to do it like that to had gnuplot paint it.
I have the following script:
####
reset
set encoding utf8
set size 1,1
set terminal epslatex
set output "direccionalidad.tex"
unset border
set polar
set angles degrees #set gnuplot on degrees instead of radians
set style line 10 lt 1 lc 0 lw 0.3
set grid polar 30 #set the grid to be displayed every 60 degrees
set grid ls 10
set trange[-90:90]
f(t)=27.934*sin(1.81651*t+96.1991) # Theorical line
set xrange[-31:32]
set yrange[-30:30]
set xtics axis #disply the xtics on the axis instead of on the border
set ytics axis
set xtics scale 0 #"remove" the tics so that only the y tics are displayedj
set ytics (0, 6, 12) #make the ytics go from the center (0) to 6000 with incrment of 1000
unset ytics
set xtics ("5" 6, "15" 16.5, "30" 32)
# set the xtics only go from 0 to 6000 with increment of1000 but do not display anything. This has to be done otherwise the grid will not be displayed correctly.
set rtics (5,15,30)
set rtics format ' ' scale 0
set_label(x, text) = sprintf("set label '%s' at (32*cos(%f)), (32*sin(%f)) center", text, x, x) #this places a label on the outside
eval set_label(0, "0")
eval set_label(30, "30")
eval set_label(60, "60")
eval set_label(90, "90")
eval set_label(120, "120")
eval set_label(150, "150")
eval set_label(180, "180")
eval set_label(-150, "-150")
eval set_label(-120, "-120")
eval set_label(-90, "-90")
eval set_label(-60, "-60")
eval set_label(-30, "-30")
set size square
#PLOTS
plot "direccionalidaddatos.txt" u 1:3 pointtype 7 ps 2 lt 1 lw 3 lc rgb 'blue' notitle ,\
f(t) dt '-' lc rgb 'blue' notitle
#ACABAMOS
###
And here there are some examples of columns in the direccionalidaddatos.txt archive, the column in the middle it's just the angle in radians but it's usless cause i just want the angle in degrees so just ignore it ;):
-90 -1.570796327 0.1
-85 -1.483529864 0.2
-80 -1.396263402 0.4
-75 -1.308996939 0.7
-70 -1.221730476 1.1
-65 -1.134464014 1.7
-60 -1.047197551 2.5
#
And the result it is the image Polar plot
As you see in the image there are two branches that have no points, i want those branches to simply don't disappear cause they don't mean notihng in the graphic.So if anyone knows a form to made dissapear the branches, or to improve the script let me know hehe.
Thanks so much.
Can you just reduce the sampled range for the second plot component?
plot "direccionalidaddatos.txt" u 1:3 pointtype 7 ps 2 lt 1 lw 3 lc rgb 'blue' notitle ,\
[-52:45] '+' using 1:(f($1)) with lines dt '-' lc rgb 'blue' notitle
I have to "reinvent" a diagram like the following:
My problem is, the "filledcurves" option does not work correctly, if I use the different scaled y-axis.
set y2tics textcolor rgb "black"
set ytics nomirror
set yrange [0:80]
set y2range [0:180]
set key off
set grid dashtype 5 # auch dt ".-." möglich
plot "klima_flach.txt" using 1:3:4 with filledcurves x1,\
"" using 1:4 with lines axis x1y2,\
"" using 1:3:xtic(2) with lines axis x1y1
The used data is the following:
0 0 11 50
1 J 10 70
2 F 11 42
3 M 12 50
4 A 15 50
5 M 18 20
6 J 22 10
7 J 25 1
8 A 25 20
9 S 23 40
10 O 20 80
11 N 25 70
12 D 11 60
Any ideas, how I can get this problem solved?
By the way: A pattern as in the original diagram... possible or not?
#Wolfgang Höfer, the scaling between the axes in such type of Walter/Lieth-climate diagrams is 2. Hence, your y-range should be [0:90] and hence scaling factor 90./180.
Nevertheless, I assume #Christoph's answer solved your problem.
To your last question: a pattern as in your picture, i.e. a vertical hatch pattern? That's what I asked here (Hatch patterns in gnuplot) recently. Apparently, it's seems not possible in gnuplot.
Some time ago, I also "struggled" with climate diagrams, i.e. with filledcurves and even nonlinear axes. I would like to provide the code which I ended up. Maybe it will be useful to you or to others to draw such climate diagrams with gnuplot. If you are reading from a file, replace $DataIn with your filename. Suggestions and improvements are welcome.
# Walter/Lieth climate diagram with nonlinear axis
reset session
set encoding "utf8"
$DataIn <<EOD
# Mumbai/India, 18°54'N/72°49'E, 11 m
# No. Month Temperature Precipitation
1 January 23.9 3
2 February 23.9 3
3 March 26.1 3
4 April 28.1 2
5 May 29.7 18
6 June 28.9 485
7 July 27.2 617
8 August 27.0 340
9 September 27.0 264
10 October 28.1 64
11 November 27.2 13
12 December 25.6 3
EOD
# in order to be flexible for different input files
ColTemp = 3 # col# temperature
ColPrec = 4 # col# precipitation
# get location label from first commented row starting after '# '
set datafile commentschar "" # set the comment char to none
set datafile separator "\n" # data will be a full line
set table $Dummy # plot following data to a dummy table
# plots only first line 'every ::0::0' as string to the dummy table
# and assigns this line starting after the 3rd character to variable 'Location'
plot $DataIn u (Location = stringcolumn(1)[3:]) every ::0::0 with table
unset table # stop plotting to table
set datafile commentschar "#" # restore default commentschar
set datafile separator whitespace # restore default separator
set label 1 at graph 0.02,0.96 Location font ",10" # put label on graph
# set periodic boundaries, i.e. add lines of Dec and Jan again
# independent of the input format $DataIn, column1 of $Data will be the number of month
set datafile separator "\n"
set table $Data
plot $DataIn u (0):(stringcolumn(1)) every ::11::11 with table
plot $DataIn u ($0+1):(stringcolumn(1)) with table
plot $DataIn u (13):(stringcolumn(1)) every ::0::0 with table
unset table
set datafile separator whitespace
# print $Data
# settings for nonlinear scale
ScaleChangeAt = 100.
ScaleChangeFactor = 5.
f1(y) = (y<=ScaleChangeAt) ? y : ((y - ScaleChangeAt)/ScaleChangeFactor + ScaleChangeAt)
f2(y) = (y<=ScaleChangeAt) ? y : ((y - ScaleChangeAt)*ScaleChangeFactor + ScaleChangeAt)
f3(y) = f1(y)/2. # relation between axes y and y2; standard for Walter/Lieth climate diagrams
set nonlinear y2 via f1(y) inverse f2(y)
# settings for x-axis
set xrange[0.5:12.5]
set xtics 1 scale 0,1
set mxtics 2
set grid mxtics
# create months labels from local settings
do for [i=1:12] {
set xtics add (strftime("%b",strptime("%m",sprintf("%g",i))) i)
}
# settings for y- and y2-axes
stats [*:*] $DataIn u ColTemp:ColPrec nooutput
Round(m,n) = int(m/n)*n + sgn(m)*n
Ymin = STATS_min_x > 0 ? 0 : Round(STATS_min_x,10)
Ymax = 50
Y2min = Ymin < 0 ? f1(Ymin)*2 : 0
Y2max = Round(STATS_max_y,10**int(log(STATS_max_y)/log(10))) # round to next 10 or 100
# print Ymin, Ymax, Y2min, Y2max
# y-axis
set ylabel "Temperature / °C" tc rgb "red"
set yrange [Ymin:f3(Y2max)] # h(Y2max)]
set ytics 10 nomirror tc rgb "red"
# "manual" setting of ytics, up to 50°C
set ytics ("0" 0)
do for [i=Ymin:50:10] {
set ytics add (sprintf("%g",i) i)
}
# settings for y2-axis
set y2label "Precipitation / mm" tc rgb "blue"
set y2range [Y2min:Y2max]
# "manual" setting of y2tics
set y2tics nomirror tc rgb "blue"
set y2tics ("0" 0)
set grid y2tics
do for [i=20:ScaleChangeAt:20] {
set y2tics add (sprintf("%g",i) i)
}
do for [i=ScaleChangeAt:Y2max:20*ScaleChangeFactor] {
set y2tics add (sprintf("%g",i) i)
}
plot \
$Data u 1:ColTemp+1:(f3(column(ColPrec+1))) axis x1y1 w filledcurves above lc rgb "yellow" not,\
'' u 1:ColTemp+1:(f3(column(ColPrec+1))) axis x1y1 w filledcurves below fs pattern 4 fc rgb "blue" not,\
'' u 1:(f3(ScaleChangeAt)):(f3(column(ColPrec+1))) axis x1y1 w filledcurves below fs solid 1.0 fc rgb "blue" not,\
'' u 1:ColTemp+1 w l lw 2 lc rgb "red" not,\
'' u 1:ColPrec+1 axes x1y2 w l lw 2 lc rgb "blue" not
### end of code
which results in:
The filledcurves doesn't have an option for choosing different axes for the y-values in column two and three. But you are in the lucky situation, that you have fixed y-ranges. So you can define a scaling function for one of the columns:
set y2tics textcolor rgb "black"
set ytics nomirror
set yrange [0:80]
set y2range [0:180]
scale = 80.0/180.0
set key off
set grid dashtype 5 # auch dt ".-." möglich
plot "klima_flach.txt" using 1:3:(scale*$4) with filledcurves,\
"" using 1:4 with lines axis x1y2,\
"" using 1:3:xtic(2) with lines axis x1y1
I am creating a seemingly duplicate question posted by Matt in 2015, however, the answer posted by Christoph doesn't work at the moment for me, since I'm using Gnuplot 5.2.
When I use Matt's input date and Christoph's script, I end up with this result:
Picture here
As can be seen, the bottom half (3rd & 4th quadrant) of the plot is plotted, yet it should not be.
reset
set terminal pngcairo font ',10'
set polar
set angle degrees
set size ratio 1
set lmargin 8
set style line 11 lc rgb 'gray80' lt -1
set grid polar ls 11
unset border
unset tics
set xrange [-1:1]
set yrange [0:1]
set size ratio -1
r = 1
set rtics 0.166 format '' scale 0
set label '0°' center at first 0, first r*1.05
set label '-90°' right at first -r*1.05, 0
set label '+90°' left at first r*1.05, 0
set for [i=1:5] label at first r*0.02, first r*((i/6.0) + 0.03) sprintf("%d dB", -30+(i*5))
unset raxis
set key outside top right
set output 'polar.png'
plot 'norm_polar_1000.txt' w lp ls 1 t '1k'
Data:
180 0.657067
172.5 0.6832
165 0.717767
157.5 0.7461
150 0.7747
142.5 0.806167
135 0.835633
127.5 0.865167
120 0.890533
112.5 0.918133
105 0.929633
97.5 0.9566
90 0.9632
82.5 0.9566
75 0.929633
67.5 0.918133
60 0.890533
52.5 0.865167
45 0.835633
37.5 0.806167
30 0.7747
22.5 0.7461
15 0.717767
7.5 0.6832
0 0.657067
To get to my own problem, I would like to get a very similar plot but with only 2nd and 3rd quadrant instead.
My code:
reset
set terminal pngcairo font ',12'
set polar
set angle degrees
set size ratio -1
set tmargin 3
set bmargin 3
set style line 11 lc rgb 'gray80' lt -1
set grid polar ls 11
unset border
unset tics
unset key
r=1
set rrange [0:r]
set xrange [-1:0]
set yrange [-1:1]
rOffset = 1.1
set rtics 0.166 format '' scale 0
set label '0°' center at first 0, first r*rOffset
set label '90°' right at first -r*rOffset, 0
set label '180°' center at first 0, first -r*rOffset
set output 'TestPolar.png'
plot 'exampleData.txt' u ($1+90):2
exampleData.txt:
10 0.1
30 0.2
50 0.3
70 0.4
90 0.5
110 0.6
130 0.7
150 0.8
170 0.9
Current resulting picture here
Any ideas?
It looks to me that gnuplot's trange in 5.2 is always in radians rather than degrees, even if the data itself is in degrees. That seems like a bug but you can work around it.
In 5.2 do not set xrange or yrange to limit data in polar mode; use rrange and trange. xrange and yrange affect the entire plot layout, not just the data.
Also note that you can move the origin on theta to the top using command set theta top. If you do this you need not add 90° to each data point.
Assuming that by "only the 2nd and 3rd quadrant" you mean 90 < theta < 270, your script becomes
set polar
set angle degrees
set size ratio -1
set tmargin 3
set bmargin 3
set style line 11 lc rgb 'gray80' lt -1
set grid polar ls 11
unset border
unset tics
unset key
r=1
set rrange [0:r]
set trange [ pi/2 : 3*pi/2 ]
set theta top
set rtics 0.166 format '' scale 0
set ttics (0,90,180) format "%g°"
plot 'exampleData.txt' using ($1):2 with lines
Note that I set trange in radians rather than degrees to work around the bug.
Output using gnuplot 5.2.4 is attached
I have been learning Gnuplot for about a day now and I would like to use boxplot to spot outliers from a Data Set at a Glance.
So let us say I am conducting an experiment:
On 10 subjects
I make the 10 subjects repeat a task for a 100 times,to reach 3 specific targets.
I collect how many times they reach Target1, Target2, Target3.
Those result are gathered in the file data_File_new.dat described below:
Name Target1 Target2 Target3
subject1 10 30 50
subject2 11 31 51
subject3 9 29 49
subject4 12 32 52
subject5 8 28 48
subject6 13 33 53
subject7 7 27 47
subject8 50 34 54
subject9 6 50 46
subject10 15 35 20
Now I create a boxplot from this data
file = 'data_File_new.dat'
header = system('head -1 '.file);
N=words(header)
set title 'BoxPlot Subject Success'
set ylabel 'Number Of Success'
set xtics border in scale 0,0 nomirror norotate offset character 0, 0, 0 autojustify
set xtics norangelimit
set xtics rotate -45
set xtics ('' 2)
set for [i=2:N] xtics add (word(header, i) i)
set style data boxplot
plot for [i=2:N] file using (i):i
So the result is a boxplot with outliers being plotted as solid points (I wanted to post the picture but I need 10 reputation to post the image). It tells me whether there are outliers or not.
However I want to know more I want to know who are the outliers, that is:
Subject 8 is an outlier for Target 1
Subject 9 is an outlier for Target 2
Subject 10 is an outlier for Target 3
Since Gnuplot knows these points are outliers, I expect Gnuplot to store them in some kind of list. I would like to tell Gnuplot 'plot the outliers and label them with the word of the first column (subjectx) corresponding to the line they belong to'.
Then when I open the boxplot I can identify at a glance not only there are outliers but also who they are.
Does anyone know how to do this? I looked on the forum and saw some people doing this in R but not in Gnuplot.
It's not the prettiest bit of gnuplot code but it can be done!
Gnuplot stats can be used to obtain the upper and lower quartile, which are used to produce the boxplot. You can then use some conditional code to plot the points that lie outside the range with labels. The tricky part is that the plot command is built up as string, before being evaled at the end. Like I said, not too pretty!
file = 'data_File_new.dat'
header = system('head -1 '.file)
N=words(header)
set title 'BoxPlot Subject Success'
set ylabel 'Number Of Success'
set xtics border in scale 0,0 nomirror norotate offset character 0, 0, 0 autojustify
set xtics norangelimit
set xtics rotate -45
set xtics ('' 2)
set for [i=2:N] xtics add (word(header, i) i)
r = 1.5
set style boxplot range r
unset key
cmd = "plot for [i=2:N] file using (i):i with boxplot"
do for [i=2:N] {
stats file using i every ::1 nooutput
lq = STATS_lo_quartile
uq = STATS_up_quartile
ir = uq - lq
min = lq - r * ir
max = uq + r * ir
cmd = cmd . sprintf(", file using (%d):($%d < %d || $%d > %d ? $%d : 1/0):1 every ::1 with labels offset 5,0", i, i, min, i, max, i)
}
eval cmd
I have this points:
0.00049 1.509
0.00098 1.510
0.00195 1.511
0.00293 1.509
0.00391 1.510
0.00586 1.523
0.00781 1.512
0.01172 1.514
0.01562 1.510
0.02344 1.511
0.03125 1.510
0.04688 7.053
0.06250 7.054
0.09375 7.187
0.125 7.184
0.1875 7.177
0.25 7.207
0.375 16.588
0.5 24.930
0.75 39.394
1 56.615
1.5 77.308
2 84.909
3 89.056
4 88.485
6 88.678
8 89.022
12 88.513
16 88.369
24 88.512
32 88.536
48 87.792
64 87.716
96 87.589
128 87.608
192 87.457
256 87.388
And this gnuplot script:
#! /usr/bin/gnuplot
set terminal png
set output "lat_mem_rd.png"
set title "Memory Latency Benchmark (Stride 512)"
set xlabel "Memory Depth (MB)"
set ylabel "Latency (ns)"
set xtics rotate by 45 offset 0,-1
set xtics font "Times-Roman, 8"
set grid
set style line 1 lc rgb '#0060ad' lt 1 lw 2 pt 7 ps 1 # --- blue
plot "lat_mem_rd.dat" using (log($1)):2:xtic(1) smooth unique title "" with linespoints ls 1
which generates this graphic:
But i want to show the y values in the y label with one of the approximated values in those approximations, for example, for all of the values with x values between 3 and 256, the y label is set to just one, maybe 88.513 that corresponds to x=12 or other (or maybe the average of those points if its not very difficult)...
The same for x values between 0 and 0.02344 and for x values between 0.03125 and 0.1875.
This y values will substitute the values 10, 20, ..., 90.
Here is a modification of your script that might do what you want, if I understand you correctly:
set title "Memory Latency Benchmark (Stride 512)"
set xlabel "Memory Depth (MB)"
set ylabel "Latency (ns)"
set xtics rotate by 45 offset 0,-1
set xtics font "Times-Roman, 8"
set grid
a = ""; p = 0; nn = 1; nt = 37; d = 4; s = 0
f(x) = (x>p+d || nn >= nt)?(nn=nn+1, p=x, a=a." ".sprintf("%5.2f", s/n), n=1, s=x):(nn=nn+1, p=x, s=s+x, n=n+1)
plot "lat_mem_rd.dat" using 1:(f($2)) # Just to set array "a"
set ytics 0,0,0
set yrange [0:90]
set for [aa in a] ytics add (aa aa)
set style line 1 lc rgb '#0060ad' lt 1 lw 2 pt 7 ps 1 # --- blue
set terminal png
set output "lat_mem_rd.png"
plot "lat_mem_rd.dat" using (log($1)):2:xtic(1) smooth unique title "" with linespoints ls 1
This script produces this plot:
The strategy is to accumulate a sum of Y-values and calculate an average every time the Y-value increases by at least an amount d; these averages are stored in a string variable "a", which is looped over to set the ytic values before the final plot command. This way clusters of closely-spaced Y-values give rise to a ytic at their average value; I think that was what you wanted.