does anyone know how I can achieve drawing triangle on level sets of some 3d function (something like on this image in gnuplot? When I tried doing this after reading some tutorials:
gnuplot> set border 15 front linetype -1 linewidth 1.000
gnuplot> set logscale z 10
gnuplot> set view map
gnuplot> set isosamples 60, 60
gnuplot> unset surface
gnuplot> set contour base
gnuplot> unset clabel
gnuplot> set style data lines
gnuplot> set ticslevel 0
gnuplot> set noztics
gnuplot> set title "Trwa symulacja"
gnuplot> set xlabel "x"
gnuplot> set xrange [ * : * ] noreverse nowriteback
gnuplot> set ylabel "y"
gnuplot> set zlabel ""
gnuplot> set yrange [ * : * ] noreverse nowriteback
gnuplot> set zrange [ * : * ] noreverse nowriteback
gnuplot> splot [-10.5:10.5] [-10.5:10.5] x**2 +y**2 with lines lc rgb "#000000"
notitle,\
>'-' with lines notitle
input data ('e' ends) > 5.39703780733842 0.424994542694183 29.3086374551602
input data ('e' ends) > -4.80045950473308 -8.66307635892326 98.0933034571172
input data ('e' ends) > -3.56740563691939 3.31903046267993 23.7423461905216
input data ('e' ends) > 5.39703780733842 0.424994542694183 29.3086374551602
input data ('e' ends) > e
But I'm still getting warning: "Cannot contour non grid data. Please use "set dgrid3d".".
You need to have surface turned on for the whole splot and to turn it off for the parts where you don't want it. (You can't do it the other way round; the splot syntax only allows suppression of surfaces and not re-enabling them.)
# All the other settings you were using...
set surface
splot [-10.5:10.5] [-10.5:10.5] \
x**2 +y**2 with lines lc rgb "#000000" notitle nosurface, \
'-' with lines notitle
5.39703780733842 0.424994542694183 29.3086374551602
-4.80045950473308 -8.66307635892326 98.0933034571172
-3.56740563691939 3.31903046267993 23.7423461905216
5.39703780733842 0.424994542694183 29.3086374551602
e
Related
I'm making a weather display graph using GNUplot with a weather API. I'm currently plotting the next 48 hours of temperature and rainfall.
As you can see in the above image, the temperature is the line with the axis defined on the left; while the rainfall is depicted by the bar graph (bottom left) and its axis is defined on the right. (0, 0.5, 1).
I would however like to include other data in the graph as well. The first thing I want to include is cloud cover at the top of the graph. Again as a bar graph.
I'm including a mockup that I made is a graphic editor:
Is there a way to do this with gnuplot, or will I have to use another program to accomplish it?
You have y1-axis on the left and y2-axis on the right. If you want to have a 3rd y-axis you have to shift it somehow. One way to achieve this is with multiplot, basically several plots on top of each other.
You have to make sure that all plots are using the same (fixed) margins on the canvas (automargin probably won't work) and the same xrange (the second plot takes it from the first plot). Check the following example with some random data. Certainly, some fine tuning could be done. Adapt it to your needs.
Code:
### Three y-axes
reset session
# create some test data
myTimeFmt = "%d.%m.%Y %H:%M:%S"
set print $Data
do for [i=1:48] {
myTime(i) = strftime(myTimeFmt, time(0)+i*3600)
myTemp(i) = sin(i/5.)*5 + 20 + rand(0)
myRain(i) = int(rand(0)+0.3) * rand(0)*20
myCloud(i) = rand(0)*50
print sprintf("%s %g %g %g",myTime(i),myTemp(i),myRain(i),myCloud(i))
}
set print
set key off
set margins screen 0.1, screen 0.8, screen 0.1, screen 0.94
set multiplot
set format x "%H:%M" timedate
set xtics 3600*6
set grid xtics, mxtics, ytics, mytics
##### first plot
set ylabel "Temperature °C" tc "red"
set yrange[10:30]
set ytics nomirror tc "red"
set y2label "Rain / mm" offset -1,0 textcolor rgb "blue"
set y2range[0:40]
set y2tics nomirror tc "blue"
set style fill solid 1.0
plot $Data u (timecolumn(1,myTimeFmt)):3 axes x1y1 w l lc "red", \
'' using (timecolumn(1,myTimeFmt)):4 axes x1y2 w boxes lc "blue"
unset xlabel
unset ylabel
unset y2label
unset tics
##### Second plot
set bmargin screen 0.73
set border 4
set xrange[GPVAL_X_MIN:GPVAL_X_MAX] # identical xrange like 1st plot
set y2range[100:0] reverse
plot $Data u (timecolumn(1,myTimeFmt)):5 axes x1y2 w boxes lc rgbcolor "grey"
##### Third plot (just for 3rd y-axis)
set rmargin at screen 0.9
set border 8 # only right border visible
set y2label "Cloud coverage" offset -1,0 textcolor rgb "black"
set y2tics nomirror offset 0,0
plot NaN # plot some dummy
unset multiplot
### end of code
Result:
I need to plot spectra and in addition, I want to show some typical spectral lines. This is done with an automatically generated script for thousands of spectra, so I don't have the possibility to choose the lines to show for each spectrum, they should be chosen automatically by the xrange oder yrange. Sadly this ranges don't seem to work for arrows and so I need some other idea to prevent lines from being shown outside of the plot. I tried it with if-conditions, but this brings no change strangely.
Here is some extract from the script:
set terminal png size 1000,1414
set output "FeLoBAL_plot_1.png"
set multiplot layout 4,1 title "FeLoBAL-Spektren des SDSS DR12"
unset xrange
unset yrange
stats '170.txt' using 2 name "Fluss" nooutput
stats '170.txt' using 1 name "A" nooutput
set xlabel 'Wellenlaenge [{\305}]'
set ylabel 'Fluss [erg/cm²/s/{\305}]'
set yrange [-0.5:(Fluss_mean*3)]
set xrange [(A_min/(1.699+1)):(A_max/(1.699+1))]
p '170.txt' u (($1)/(1.699+1)):2 with lines title "Nr.: 170; J000256.55+092025.5; z=1.699"
if(2799 > (A_min/(1.699+1)+20) && 2799 < (A_max/(1.699+1)-20)){set arrow from 2799, graph 0 to 2799, graph 1 nohead; set label "Mg II" at 2804, graph 0.8 }
if(1908 > (A_min/(1.699+1)+20) && 1908 < (A_max/(1.699+1)-20)){set arrow from 1908, graph 0 to 1908, graph 1 nohead; set label "C III" at 1913, graph 0.8 }
if(1549 > (A_min/(1.699+1)+20) && 1549 < (A_max/(1.699+1)-20)){set arrow from 1549, graph 0 to 1549, graph 1 nohead; set label "C IV" at 1554, graph 0.8 }
if(1240 > (A_min/(1.699+1)+20) && 1240 < (A_max/(1.699+1)-20)){set arrow from 1240, graph 0 to 1240, graph 1 nohead; set label "N V" at 1245, graph 0.8 }
if(6562 > (A_min/(1.699+1)+20) && 6562 < (A_max/(1.699+1)-20)){set arrow from 6562, graph 0 to 6562, graph 1 nohead; set label "H{/symbol a}" at 6567, graph 0.8 enhanced }
if(4861 > (A_min/(1.699+1)+20) && 4861 < (A_max/(1.699+1)-20)){set arrow from 4861, graph 0 to 4861, graph 1 nohead; set label "H{/symbol b}" at 4866, graph 0.8 enhanced }
if(4959 > (A_min/(1.699+1)+20) && 4959 < (A_max/(1.699+1)-20)){set arrow from 4959, graph 0 to 4959, graph 1 nohead; set label "O III" at 4964, graph 0.8 }
if(5007 > (A_min/(1.699+1)+20) && 5007 < (A_max/(1.699+1)-20)){set arrow from 5007, graph 0 to 5007, graph 1 nohead; set label "O III" at 5012, graph 0.8 }
if(4340 > (A_min/(1.699+1)+20) && 4340 < (A_max/(1.699+1)-20)){set arrow from 4340, graph 0 to 4340, graph 1 nohead; set label "H{/symbol g}" at 4345, graph 0.8 enhanced }
if(1216 > (A_min/(1.699+1)+20) && 1216 < (A_max/(1.699+1)-20)){set arrow from 1216, graph 0 to 1216, graph 1 nohead; set label "L{/symbol a}" at 1221, graph 0.88 enhanced }
Does anyone an idea of improving this or see the error, why this doesn't work properly?
Thank you!
I am unfamiliar with using if-statements in gnuplot. When i needed to do something remotely similar I used the ternary operator. It would be something like:
(Amin+20 < 1200 && Amax-20 > 1200) ? {set label 'blabla'} :\
(Amin+20 < 1500 && Amax-20 > 1500) ? {set label 'blibla'} :\
...
(Amin+20 < 1800 && Amax-20 > 1800) ? {set label 'blubla'} : 1/0
Also I would add these before the plot statement, but may be it doesn't matter. I think that with your statement many of them might be true at the same time, if for example A_min is very small and A_max is very large. With the ternary constract the first true statement is evaluated (more like an if-elseif-construct).
Another danger that can occur, depending on in what kind of environment you are using this script, is that the labels get set and never get unset. In that way, as soon as the statement becomes true it is true for the rest of the session and all coming plots get it. So you could try adding
unset label
unset arrow
in the beginning of the script.
The two commands set arrow and set label do not respect the plotting area, because they are meant for decorating a figure everywhere.
Put the labels and their position in a data file and plot that.
Create a file labels.txt with
2799 "Mg II"
1908 "C III"
1549 "C IV"
1240 "N V"
6562 "H{/symbol a}"
4861 "H{/symbol b}"
4959 "O III"
5007 "O III"
4340 "H{/symbol g}"
1216 "L{/symbol a}"
And then plot it with
reset
stats '170.txt' using 2 name "Fluss" nooutput
stats '170.txt' using 1 Name "A" nooutput
x(v) = v / (1.699+1)
ymin = -0.5
ymax = Fluss_mean*3
ylbl = ymin + 0.8 * (ymax - ymin)
set yrange [ymin:ymax]
set xrange [x(A_min):x(A_max)]
plot '170.txt' u (x($1)):2 with lines, \
'labels.txt` u 1:(ylbl):2 with labels enhanced t '',\
'' u 1:(ymin):(0):(ymax - ymin) with vectors nohead t ''
Since you cannot use graph coordinates for plot, you must calculate the equivalent values, which isn't a problem since you use stats anyway.
I need to make some pie charts using Gnuplot. I used the code I found here, on SO. My data file looks like this:
Województwo Suma
Dolnośląskie 3.6
Kujawsko-Pomorskie 7.5
Lubelskie 4.7
Lubuskie 3.3
Łódzkie 8.1
Małopolskie 6.9
Mazowieckie 12.5
Opolskie 2.6
Podkarpackie 6
Podlaskie 3.4
Pomorskie 8
Śląskie 14
And my Gnuplot script:
#!/usr/bin/gnuplot
set encoding utf8
set datafile separator "\t"
set termoption enhanced
set terminal epscairo enhanced color dashed rounded size 8.5, 5.5
set output '2008-2015procent_pie.eps'
stats '2008-2015procent_pie.csv' u 2 noout # get STATS_sum (sum of column 2)
ang(x)=x*360.0/STATS_sum # get angle (grades)
perc(x)=x*100.0/STATS_sum # get percentage
set size square # square canvas
set xrange [-1:1.5]
set yrange [-1.25:1.25]
set style fill solid 1
unset border # remove axis
unset tics # remove tics on axis
unset colorbox # remove palette colorbox
unset key # remove titles
Ai = 0.0; Bi = 0.0; # init angle
mid = 0.0; # mid angle
i = 0; j = 0; # color
yi = 0.0; yi2 = 0.0; # label position
set palette defined (1 1 0.788 0.055, 2 0.090 0.161 0.659)
plot for [i=1:STATS_records] '2008-2015procent_pie.csv' u (0):(0):(1):(Ai):(Ai=Ai+ang($2)):(i) every ::i::i with circle linecolor palette,\
'2008-2015procent_pie.csv' u (mid=(Ai+ang($2)), Ai=2*mid-Ai, mid=mid*pi/360.0, -0.5*cos(mid)):(-0.5*sin(mid)):(sprintf('%.1f\%', $2, perc($2))) ever\
y ::1 w labels center font ',10',\
for [i=1:STATS_records] '2008-2015procent_pie.csv' u (1.45):(i*0.25):1 every ::i::i with labels left,\
for [i=1:STATS_records] '+' u (1.3):(i*0.25):(i) pt 5 ps 4 lc palette
I have 2 problems with this script:
I don't see all labels, is it possible to move the labels somehow that I could see them all?
Colours: here, on my pie chart I have basically only 2 colours - yellow and blue. How to make it so I could have a variety of colours, different colour for different value?
My chart looks like this now:
Thank you.
-----------------------------------------------------------------------------------------------------------------------------------EDIT
-----------------------------------------------------------------------------------------------------------------------------------
I changed a bit my script, as suggested by #RolandSmith, also, I modified a little my data file, Now it looks like this:
Województwo Suma
Dolnośląskie 3.6
Kujawsko-Pomorskie 7.5
Lubelskie 4.7
Lubuskie 3.3
Łódzkie 8.1
Małopolskie 6.9
Mazowieckie 12.5
Opolskie 2.6
Podkarpackie 6
Podlaskie 3.4
Pomorskie 8
Śląskie 14
Świętokrzyskie 2.8
Warmińsko-Mazurskie 4
Wielkopolskie 7.9
Zachodniopomorskie 4.6
And the modified script:
#!/usr/bin/gnuplot
set encoding utf8
set datafile separator "\t"
set termoption enhanced
set terminal epscairo enhanced color dashed rounded size 8.5, 5.5
set output '2008-2015procent_pie.eps'
stats '2008-2015procent_pie.csv' u 2 noout # get STATS_sum (sum of column 2)
ang(x)=x*360.0/STATS_sum # get angle (grades)
perc(x)=x*100.0/STATS_sum # get percentage
set size square # square canvas
set xrange [-1:1.5]
set yrange [-1.25:1.25]
set style fill solid 1
unset border # remove axis
unset tics # remove tics on axis
unset colorbox # remove palette colorbox
unset key # remove titles
Ai = 0.0; Bi = 0.0; # init angle
mid = 0.0; # mid angle
i = 0; j = 0; # color
yi = 0.0; yi2 = 0.0; # label position
set palette rgb 33,13,10;
plot for [i=1:STATS_records] '2008-2015procent_pie.csv' u (0):(0):(1):(Ai):(Ai=Ai+ang($2)):(i) every ::i::i with circle linecolor palette,\
'2008-2015procent_pie.csv' u (mid=(Ai+ang($2)), Ai=2*mid-Ai, mid=mid*pi/360.0, -0.5*cos(mid)):(-0.5*sin(mid)):(sprintf('%.1f\%', $2, perc($2))) every ::1 w labels center font ',10',\
for [i=1:STATS_records] '2008-2015procent_pie.csv' u (1.45):(i*0.25)-1.9:1 every ::i::i with labels left,\
for [i=1:STATS_records] '+' u (1.3):(i*0.25)-1.9:(i) pt 5 ps 4 lc palette
Now the problem is with labels - I still can't see all of them. There should be 16 labels, as you can see from the CSV file. I tried to change the page size, with no success. Thank you for help.
Current pie:
To move the labels in the pie-chart inwards or outwards, change the "-0.5" in front of the sin and cos. To move the labels and the color-squares, change (i*0.25) to (i*0.25)-1.2 in the third and fourth plot.
Update: Change (i*0.25) to e.g. (i*0.18) to make the distance between the labels smaller. And change ps 4 to e.g. ps 3 to make the squares smaller.
Define a larger palete. Your current one only has two entries. Get one with as least as much colors as you have entries. You could use colorbrewer to generate palette colors.
Some other points.
While this is really very clever, you're probably pushing gnuplot way beyond what it was intended. Consider using another tool like e.g. Python's matplotlib.
Your data doesn't add up to 100, but only to 80.6. So you should scale your figure properly using the ang and perc functions. I can't put my finger on it, but it doesn't look right.
In the sprintf, you should only use the percentage:sprintf('%.1f\%', perc($2))
I'd like to relabel the radial tick markers in the following polar log plot:
f = figure ;
t = 0:0.01: pi/2 ;
polar(t, 10 * log10(cos(t))/(50) + 1)
from 1, 0.8, 0.6, 0.4, 0.2 to 0, -10, -20, -30, -40 (i.e. radial dB ticks).
Trying some of the methods from Fixing the Radial Axis on MATLAB Polar Plots, I was able to relabel the markers provided my tick markers were positive and increasing.
I tried the following based on How to remove Rho labels from Matlab polar plot?
rho_labels = {'1' '0.8' '0.6' '0.4' '0.2'};
rho_labels2 = {'0' '-10' '-20' '-30' '-40'};
for r=1:length(rho_labels)
ff = findall(f, 'string', rho_labels{r}) ;
ff = rho_labels2{r} ;
end
but it also didn't work (seems to do nothing, so I suspect I'm operating on a copy of the find results not handled).
How can these tick markers be adjusted? Also, if I wanted a different number of concentric circles than 5, how can that be done (for example, 4 subdivisions with -40 dB at the "origin".)
Here is a way to rename the radial tick labels. Be warned that if there is a match between any radial and angular tick mark labels, both will be replaced and the angular labels will be wrong. But the angular tick labels are fixed as 0, 30, 60, ..., 330, so as long as the radial tick labels don't include these values, you should be fine.
What the code does is find all the text in the plot using findall, trim the blank spaces at the front of each string, then, for each entry in rho_labels, set the string entry corresponding to the tick label with that identifier to the corresponding entry in rho_labels2.
f = figure ;
t = 0:0.01: pi/2 ;
polar(t, 10 * log10(cos(t))/(50) + 1)
rho_labels = {'1' '0.8' '0.6' '0.4' '0.2'};
rho_labels2 = {'0' '-10' '-20' '-30' '-40'};
ff = findall(f,'type','text');
t=strtrim(get(ff,'String'));
for r=1:length(rho_labels)
set(ff(strcmp(t,rho_labels{r})),'String',rho_labels2{r})
end
To modify the number of rings, I think think of anything better than modifying polar.m and creating your own custom polarMOD.m function. If you do this you can also do the radial labels as well. In fact, there might be such a function on the MathWorks File Exchange.
I have (for me) a strange problem with the date on the x-axis.
I use the (imo) linux time in the first column like;
1385856000,1.69,0,10.33,0,1.69,10.33,-8.64,12.14,3.5
1385942400,0,0.94,3.33,8.51,0.94,11.84,-10.9,13.7,2.8
1386028800,0,0.51,4.96,8.65,0.51,13.61,-13.1,15.8,2.7
1386115200,0,0.01,3.42,6.49,0.01,9.91,-9.9,10.6,0.7
V
V
V
1388361600,0,0.63,4.21,7.65,0.63,11.86,-11.23,13.93,2.7
1388448000,0,0.18,4.47,8.29,0.18,12.76,-12.58,14.48,1.9
In this case december 2013 with 31 days. But the line begins with 30 (november?).
For now a draw a rectangle over de "30" but ofcourse thats not the way.
This is my script;
maand = "Dec"
jaar = "2013"
file = maand.jaar.'.txt'
set output maand.jaar.".png"
set datafile separator ","
set linestyle 1 lt 1 lc rgb "black"
set linestyle 2 lt 1 lc rgb "red"
set bmargin 2.2 # witruimte onder grafiek
set label font "arial, 7" # grootte font tbv labels in het grafiek
set boxwidth 0.8 relative
set terminal pngcairo truecolor enhanced size 1200, 500 background rgb "#FFF5F5"
stats file using 0 nooutput ; dagen = STATS_records
stats file using 10 nooutput ; zon = value(int(STATS_sum*1000))
stats file using 9 nooutput ; gebruikt = value(int(STATS_sum*1000))
afgenomen = gebruikt-zon
set timefmt "%s" ; fmt = "%s"
stats file using (strptime(fmt, stringcolumn(1))) every ::1::1 nooutput
maand = strftime("%B", STATS_max) ; jaar = strftime("%Y", STATS_max) ; datum = maand." ".jaar
set title 'Energie stromen '.datum font "arial bold, 14"
set xdata time ; set timefmt "%s" ; set format x "%d" # dit is de opmaak zoals je hem gaat zien
set xtics 86400 font "arial,12" offset -1.35,0.5
set mxtics 1
set grid ls 1 lc rgb "#dddddd"
set ytics font "arial, 12" offset 0.5,0
set ylabel "V e r m o g e n in kW" offset 3,1 font "helvetica, 12"
unset key
set key below left samplen 2
set key maxrows 1 # aantal regels onder het grafiek (met Watt/uur erin)
set style fill solid 1 border 0.5 # was transparent solid 0.5 border 0.5
set style rectangle fc linestyle 1 fs solid 0.5 noborder
set object rectangle front fillcolor rgb "#FFF5F5"
set object 2 rect from graph -.48, graph -1.5 to graph -0.004, graph 0.02 fc rgb "#FFF5F5"
plot file u ($1-43200):10 w boxes lc rgb "#00ff00" title "Deze maand zon: ".(zon/1000)." kW",\
file u ($1-43200):10:(sprintf("%2.1f",$10)) w labels offset 0.0,0.4 font "arial, 10" notitle,\
file u ($1-43200):(-1*$9) w boxes lc rgb "#ff0000" title "&{2}Verbruik: ".(gebruikt/1000)." kW",\
file u ($1-43200):(-1*$9):(sprintf("%2.1f",$9)) w labels offset 0,-0.4 font "arial, 10" notitle
Has some one a clou?
The 30 comes from november and the way you shift the xticlabels.
I think, the best way to have the labels below the boxes, but the tics and the grid lines between the boxes is the following:
Scale the major tics to 0
Add one minor xtic and draw the grid lines only for the minor xtics
Do not expand the automatic xrange to the next major tic (set autoscale xfix)
Plot the boxes at their actual time position (plot file u 1:... instead of plot file u ($1-43200):...)
...
set xtics 86400 font "arial,12" scale 0, 1
set mxtics 2
set grid mxtics ytics ls 1 lc rgb "#dddddd"
set autoscale xfix
...
plot file u 1:10 w boxes lc rgb "#00ff00"
...
With these modifications, your exemplary data and version 4.6.3 I get
BTW: You can compress your three stats calls to a single one:
stats file using 9:10 nooutput
dagen = STATS_records
zon = int(STATS_sum_y*1000)
gebruikt = int(STATS_sum_x*1000)