How to properly reverse rrange in gnuplot? - gnuplot

I try to reverse the rrange of a polar gnuplot plot. According to the documentation (p. 173f) this can be achieved by swapping min and max values of the range definition or by using the reverse keyword in autoscale mode.
Neither one nor the other variant gives the results that I want.
The code:
set polar
set grid polar 30
set angle degrees
set size square
# case 1
set rrange [0:90]
# case 2
set rrange [90:0]
# case 3
set rrange [*:*] reverse
plot "-" u 1:2 w p pt 7 ps 3
0 30
30 60
60 45
e
The results:
The first picture shows a range of [0:90], the second one the range of [90:0] where no point is visible at all.
Plot three shows the output of the reverse setting.
As the documentation for rrange states
[...] no point with radius greater than < rmax > will be plotted.
the behavior of case 2 is totally comprehensible. On the other hand, case 3 should give the same result according to the following:
The reverse option reverses the direction of an autoscaled axis. For example, if the data values range from 10 to 100, it will autoscale to the equivalent of set xrange [100:10].
There seems to be some inconsistency between the documentation and the actual behavior of gnuplot.
This leads me to my question: How can I plot a diagram with the radius axis ranging from 90 in the middle to 0 at the outer circle?
EDIT
A small explanation of the application background:
What I want to visualize is a 2D top view of a sphere with equally spaced latitudes (Azimuthal equidistant projection). There, the center represents a pole with 90 degrees of latitude which decreases along the radius.

As a side comment, note also that the behaviour of the reverse keyword has been changed in Gnuplot 5 vs Gnuplot 4:
http://gnuplot.info/ReleaseNotes_5_0.html
"set xrange [0:1] reverse" does not work any more, you have to write instead "set xrange [1:0]".

Related

Is there a way to change the y axis on Gnuplot so that my image graphs from hour 16 to hour 15 instead of 0 to 24?

I'm sorry if this has already been asked, I couldn't find it anywhere, but I have an image plot on gnuplot of a three-columned data file for a y range [0:24] and I can't figure out how to use gnuplot to rearrange the image graph so my y axis runs from 16:24 and then 0:16 (in that order and on the same axis). The command I've been using is "plot [] [0:24] '/Users/eleanor/PycharmProjects/attempt2.gray' u 1:2:3 w image" but I don't know what command to use so that hour 16 is at the very bottom instead of 0, and then when y reaches 23:59 y goes to 0 next and then continues increasing up to 15:59 at the very top of the axis. I'm not sure if that makes sense or not, and I've already tried changing the y range to [16:15] and that did nothing except give me an error lol. Any tips would be very much appreciated! :)
a piece of the file im using is below (with the first column being the day of year, the second being the time in decimal hours, and the third being the data):
20 0.0 7.327484247409568
20 0.002777777777777778 8.304658863945411
20 0.005555555555555556 11.641408500506405
20 0.008333333333333333 6.543382279013497
20 0.011111111111111112 13.922090817182697
20 0.013888888888888888 10.696406455987988
20 0.016666666666666666 12.537636516165243
20 0.019444444444444445 11.816216763447612
20 0.022222222222222223 8.914413125514413
20 0.025 5.8225423124691496
20 0.027777777777777776 10.896730484548698
20 0.030555555555555555 9.097140108173859
As currently implemented, with image treats the entire block of data as a single entity. You can't chop it up into pieces within a single plot command. However if your data is dense enough, it may be that you can approximate the same effect by plotting each pixel as a colored square:
set xrange [*:*] noextend
set yrange [0:24]
plot 'datafile' using 1:(($2>16.)? ($2-16.) : ($2+8.)):3 with points pt 5 lc palette
I strongly recommend not making the range limits part of the plot command. Set them beforehand using set xrange and set yrange.
If necessary, you can adjust the size of the individual square "pixels" by using set pointsize P where P is a scale factor. It probably looks best if you make the points just large enough (or small enough) to touch each other. I think the default ones in the image I show are too large.
You can also use the boxxyerror plotting style instead of the image plotting style. Well, here's what the help for boxxyerror says
gnuplot> ? boxxyerror
The `boxxyerror` plot style is only relevant to 2D data plotting.
It is similar to the `xyerrorbars` style except that it draws rectangular areas
rather than crosses. It uses either 4 or 6 basic columns of input data.
Additional input columns may be used to provide information such as
variable line or fill color (see `rgbcolor variable`).
4 columns: x y xdelta ydelta
6 columns: x y xlow xhigh ylow yhigh
....
If you adopt the four-column plotting style above, you must specify xdelta and ydelta in addition to x and y to specify the rectangle. The xdelta and ydelta should be the half-width and half-height of each pixel. From your data, let's say xdelta is half of 1 and ydelta is half of 0.002777777777777778 hours.
Our final script will look like this.
In this script, the second column of "using" is the same as Ethan's answer.
dx = 1.0/2.0
dy = 0.002777777777777778/2.0
set xrange [-1:32]
set yrange [0:24]
set ytics ("16" 0, "20" 4, "0" 8, "4" 12, "8" 16, "12" 20, "16" 24)
set palette defined (0 "green", 0.5 "yellow", 1 "red")
unset key
plot "datafile" using 1:($2>16?($2-16):($2+8)):(dx):(dy):3 \
with boxxy palette

Gnuplot: How to plot a 45 degree line?

I want to plot data from two different years and insert a 45 degree line so you can easily see if the value increased or decreased. X- and Y-axis will be from 0 to 1.
Thanks in advance for any help, much appreciated!
As Thor says, 45 degrees can be plotted simply by using plot x.
For a more general solution, you can use tan.
For example, to plot all lines from 0 degrees to 85 degrees
set angles degrees
set xrange [0:1]
set yrange [0:1]
plot x*tan(0), x*tan(5), x*tan(10), x*tan(15), x*tan(20), x*tan(25), x*tan(30), x*tan(35), x*tan(40), x*tan(45), x*tan(50), x*tan(55), x*tan(60), x*tan(65), x*tan(70), x*tan(75), x*tan(80), x*tan(85)

gnuplot - Does `set xrange [x_min:x_max]` limit the ranged used for function fit?

Simple question - the range drawn on a plot can be changed with the set xrange [x_min:x_max] command.
Does this command also limit the range used when fitting a function using the data fitting tools in gnuplot? Is there a way to manually specify the ranged used for function fits? (One guess might be the command every? Do I need to over-ride xrange using every?)
The reason I ask is that I am using xrange to plot outputs zoomed in on the low value x region to view transient behaviour more clearly, but I think this may be "slicing off" values from the function fitting at larger x values outside the xrange region selected?
This is an old question, but the current answer is incorrect: the current settings of xrange does affect the range used for fitting if no explicit range is given as part of the fit command. This can be easily seen by a simple example: if you have a datafile test.dat that contains
1 1
2 2
3 3
4 4
5 6
6 8
7 10
8 12
and use a linear fit, you get
fit a+b*x "test.dat" via a,b
plot "test.dat" w p, a+b*x w l
and fit parameters (a,b)=(-1.42, 1.59). However, if you first set the xrange you get
set xrange [4:8]
fit a+b*x "test.dat" via a,b
plot "test.dat" w p, a+b*x w l
and fit parameters (a,b)=(-4,2).
This is at least the current behavior of gnuplot 5.2, but this old thread from 2009 suggests that this has been the behavior for quite some time.
set xrange [x_min:x_max] does not affect the range used when fitting a function.
With the fit command (the same holds for plot) you can explicitly restrict the range to fit for a variable with the following syntax:
[{dummy_variable=}{<min>}{:<max>}]
For instance you can restrict range for the x axis with:
fit [min:max] f(x) "filename"

Can You Calculate the Area of a Contour in Gnuplot?

I've been using gnuplot for a couple of weeks now. I have large data files with 23 variables, but I select specifically x-y co-ordinate data and fluorescence intensity data for my analysis.
On of the things I would like to do is a contour plot of my fluorescing particles. I should add that this contour plot is over time so there will be several spots nearly overlapping, but this is in fact the same particle. I would like to draw contours around these spots, colour code according to intensity and have the area of the contour displayed on the graph.
I have achieved all but one of these goals for my contour plot. I cannot devise a way for gnuplot to calculate and display the area within the contour. If I could then I would have an estimate of the area of my particle. I recognise my goal may be beyond the capabilities of gnuplot, but if there were a solution then it would be very neat.
Here is my script for the contour plot which as I said gives everything I need bar the area within contours.
The co-ordinates are in nanometres and each point on the dataset is the centre of a molecule. I have taken a small range of co-ordinates because there is so much data, it would not be possible to distinguish otherwise (there are over 80 000 data points). I have also set a threshold of intensity as I only want relatively bright fluorescent particles (done with set cntrparam levels incremental 8000,5000,100000). $23 and $24 are the x and y co-ordinates respectively. $12 is the intensity.
#Contour plot of Fluorescent Particle Location with Intensity
#Gnuplot script file for plotting data in file "1002 all.txt"
reset
set dgrid3d 100,1000,1
set pm3d
set isosample 30
set xlabel 'x (nm)'
set ylabel 'y (nm)'
set contour base
set cntrparam levels incremental 8000,5000,100000
unset key
unset surface
set view map
set xrange[20000:22000]
set yrange[7000:10000]
splot "1002 all.txt" using ($23<22000 && $23>20000 ?$23 : 1/0):$24<10000 && $24>7000 ?$24 : 1/0):12 with lines
set terminal push
set terminal png
set output "1002_all_fluorophores_section_contour.png" # set the output filename
set terminal png size 1280,760
replot
set output
As #Christoph says, gnuplot might not be a numerical tool, however, the calculation of a polygon area is not too complicated and can easily be done with gnuplot only. Assumption is that you have closed polygons, i.e. last point == first point, and the data of the individual polygons is separated by two empty lines.
edit: script changed to work with gnuplot 4.6.0 as well.
Data: SO28173844.dat
1 1
2 1
2 2
1 2
1 1
3 1
5 4
9 0
8 4
7 4
9 8
6 8
4 9
0 6
3 1
4 0
5 3
7 1
4 0
Script: (works for gnuplot>=4.6.0, March 2012)
### calculate areas of closed polygons
reset
FILE = "SO28173844.dat"
set size ratio -1
set style fill solid 0.3
set grid x,y front
set key noautotitle
stats FILE u 0 nooutput # get number of blocks, i.e. polygons
N = STATS_blocks
getArea(colX,colY) = ($0==0?(Area=0, x1=column(colX), y1=column(colY)) : 0, \
x0=x1, y0=y1, x1=column(colX), y1=column(colY), Area=Area+0.5*(y1+y0)*(x1-x0))
getMinMax(colX,colY) = (x2=column(colX), y2=column(colY), $0==0? (xMin=xMax=x2, yMin=yMax=y2) : \
(x2<xMin?xMin=x2:0, x2>xMax?xMax=x2:0, y2<yMin?yMin=y2:0, y2>yMax?yMax=y2:0))
Areas = Centers = ''
do for [i=1:N] {
stats FILE u (getArea(1,2),getMinMax(1,2)) index i-1 nooutput
Areas = Areas.sprintf(" %g",abs(Area))
Centers = Centers.sprintf(' %g %g',0.5*(xMin+xMax),0.5*(yMin+yMax))
}
CenterX(n) = real(word(Centers,int(column(n))*2+1))
CenterY(n) = real(word(Centers,int(column(n))*2+2))
Area(n) = real(word(Areas,int(column(n)+1)))
myColors = "0xff0000 0x00ff00 0x0000ff"
myColor(i) = sprintf("#%06x",int(word(myColors,(i-1)%words(myColors)+1)))
plot for [i=1:N] FILE u 1:2 index i-1 w filledcurves lc rgb myColor(i), \
'+' u (CenterX(0)):(CenterY(0)):(sprintf("A=%g",Area(0))) every ::0::N-1 w labels center
### end of script
Result:

Gnuplot - "zoom in" part of x-axis

I have a data row with lots of dots, plotted as markers. X-axis values range between 0 and 80 ms, and Y-values take discrete values of 1,2,..5. There are about 50000 points, so if I just plot them as usual, the Y-value changing dynamics is not clear, as you see for example a solid line forming at Y value 5, with a few dropouts at 3 and 4. I would like to modify my plot to zoom in the first millisecond - the half of the X-axis should be occupied by the range 0-1ms, and the rest 1-80ms. Any idea how to achieve this?
Use this:
set yrange [-1:1.3]
set xrange [0:12]
set x2range [40:150]
set xtics 0,1,5
set x2tics 100,10,150 mirror offset 0,-21.6
plot (x<5?sin(x):0/0) axis x1y1 tit "f(x)", (x>100?cos(x):0/0) axis x2y1 tit "g(x)"
Constant -21.6 is setting up xtics labels for second part but according to x2 (upper) axis... So you must fit this constant according to graph height and used terminal. Also you have to change range and tics settings to obtain continuous x axis.

Resources