I'm putting labels on top (offset by 10) of histogram bars like this:
plot "hist.txt" using 1:2 with boxes ls 1, "hist.txt" using 1:($2+10):(sprintf("%.1f%%",$2)) with labels
When the bar value is 87%, it draws the label.
When the bar value is 92%, the label isn't drawn, probably since there isn't enough space left. How do I tell it to draw the label anyway, and I don't mind if it would overflow the intended canvas size?
Assuming you limit the range of the y-axis to 0~100, the y-value of 92 + 10(= 102) will not be drawn because it exceeds the maximum value of yrange.
It works well if you use with labels offset 0, first 10 as the plot style specification instead of shifting the position of the label in using.
set key noautotitle
set tmargin screen 0.85
set xrange [0:11]
set yrange [0:100]
plot "hist.txt" using 1:2 with boxes ls 1, \
"hist.txt" using 1:2:(sprintf("%.1f%%",$2)) with labels offset 0,first 10
Sample "hist.txt" is,
1 30
2 60
3 87
4 92
5 50
6 20
7 10
8 30
9 50
10 40
Related
I would like to create a histogram with boxes using three pieces of data, first the number of iterations as the x-axis, then the execution time as the y-axis and finally the number of processes used.
I would like to see a bar for each number of processes used, and with a color specific to the value of the number of processes. How can I do this?
My test data is defined as:
"iterations" "processes" "time_execution"
1000 1 14
1000 2 10
1000 4 9
4000 1 60
4000 2 42
4000 4 45
7000 1 80
7000 2 70
7000 4 50
And here is my script so far, but I can't get it to place the three bars side by side:
set term svg
set output out.svg
set boxwidth 1
set style fill solid 1.00 border 0
set style histogram
set size ratio 0.8
set xlabel 'Number of iterations'
set ylabel offset 2 'Time execution in seconds'
set key left Right
set key samplen 2 spacing .8 height 3 font ',10'
set title 'Time execution per iterations and processus used'
plot test.data u 1:3:2 w boxes
Thanks!
I guess your data format doesn't fit the expected histogram format. Check the examples on the gnuplot homepage, although, I think the examples are too crowded which might be confusing and maybe the reason why there are so many histogram questions on SO.
If you modify your data format (see below) it will be easy to plot the histogram.
You can probably use any format, but the effort to prepare the data will be higher (see for example here: Gnuplot: How to plot a bar graph from flattened tables).
Script:
### plotting histogram requires suitable input data format
reset session
$Data <<EOD
xxx 1 2 4
1000 14 10 9
4000 60 42 45
7000 80 70 50
EOD
set style histogram clustered gap 1
set style data histogram
set boxwidth 0.8 relative
set style fill solid 0.3
set xlabel 'Number of iterations'
set xtics out
set ylabel 'Time execution in seconds'
set grid x,y
set key top center title "Processors"
set offset 0,0,0.5,0
plot for [col=2:4] $Data u col:xtic(1) ti col
### end of script
Result:
You can use lc variable
plot test.data u 1:3:2 w boxes lc variable notitle
EDIT
notitle is not necessary, but it makes the plot seems better.
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
Creating labels in gnulot is quite simple
set label "<value>" at <x,y> ...
But I want to read the value of a label in gnuplot from a file.
The lines in the file look this way:
...
400 300 8 0.200214 1.00193 7.42157 8.623714 86.06 13.94 1.26
800 600 1 0.2055 0.1938 34.9172 35.3165 98.86 1.14 1.00
800 600 2 0.2066 1.5514 21.1664 22.9244 92.33 7.67 1.54
800 600 4 0.2027 1.6316 14.9445 16.7788 89.06 10.94 2.10
800 600 8 0.242 1.8385 12.7261 14.8066 85.94 14.06 2.38
1024 768 1 0.2212 0.2217 55.1782 55.6211 99.20 0.80 1.00
...
I just need the values from the 10th column as labels.
Is it possible to realize something like this:
set label from <inputfile> <column_of_inputfile> <row_of_inputfile> ...
?
Thanks for any help.
This solution worked for me:
set title "800x600"
set xlabel "Nodes [#]\n"
set ylabel "Speedup" offset 2
set xrange [-0.55:3.55]
set yrange [0:5]
set style data histograms # plot boxes
set boxwidth 0.75 # have a gap between the boxes
plot 'inputfile.csv' every ::9::12 using 10:xtic(3) title "800x600" lc rgb "grey",\
'' every ::9::12 using :10:10 with labels center offset 0,1 tc rgb "black"
The first plot line does in detail:
every ::9::12 => plot line 9-12 of the inputfile.
using 10:xtic(3) => the value of column number 10 specifies the height of the data histograms. The value of column 3 is used for labeling the x axis.
The second plot line plots the content of column 10 of the lines 9-12 as label in center orientation above the data histograms.
The image shows the result.
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:
Sorry if this looks like simple question (probably) but I searched around to get some solution with no avail.
I have plot a bar graph as shown (attached) here. My problem is to adjust the spacing between label for each xtic which overlap to one another. If you notice the bar graph I attached here, at the x-axis, the "Third label" and "Fourth label long" overlap to each other. Is there anyway to control the spacing so that the labels are not overlap? Additionally, I need the legends (ring1, ring2 and ring12) to be in italics. Since I am using "terminal pngcairo", is there way to do it in italics?
set terminal pngcairo size 550,350 enhanced dash
set output "xplot_ACF_ring1-ring2-head-plots2.png"
set macro
labelFONT="font 'arial,22'"
scaleFONT="font 'arial,12'"
scaleFONT2="font 'helvetica,13'"
keyFONT="font 'arial,18'"
########################################################################################
set ylabel "Time in (ns)" #labelFONT
set ytic #scaleFONT
set xtic scale 0 #scaleFONT
set size 1.0, 1.0
########################################################################################
ring1 = "#ff0000"; ring2 = "#7FFF00"; ring12 = "#0000FF"
set auto x
set yrange [65:90]
set style data histogram
set style histogram cluster gap 1.5
set style fill solid 1.0 border -1
set boxwidth 0.9 relative
plot 'mal-cel-iso-bcm-ring1-ring2-head-bar-plot2.dat' using 2:xtic(1) ti col fc rgb ring1 ,\
'' u 3 ti col fc rgb ring2 ,\
'' u 4 ti col fc rgb ring12
The data for the above script is
Title "ring1" "ring2" "ring12"
"First label" 70 76 77
"Second label" 68 71 69
"Third label" 76 72 68
"Fourth label long" 75 76 77
Below is the plot I get after executing the script.
The re-edition of this post start here:
I would like to add error bar in this plot. The sample data is below:
Title "ring1" "ring2" "ring12"
"" 77.295326 2.2 74.829245 3.2 78.238016 2.1
"" 77.613533 6.2 74.123269 1.5 79.704782 3.6
"" 76.589653 2.1 71.704465 2.6 78.736618 4.2
"" 75.996256 0.4 73.407460 3.3 77.290057 2.5
The third fifth and seventh columns are actually the error values.
I wish may thanks in advance.
Another way to get around the problem would be to rotate the labels using:
set xtics rotate out
Or if you want to specify the rotation:
set xtics rotate by -45
There isn't an explicit option to prevent overlapping of labels.
In your example it is enough to decrease the white spacing to the left and right plot border a bit with
set offset -0.3,-0.3,0,0
which gives you with version 4.6.3:
Other options are e.g.
Increase the canvas size (set terminal ... size ...). Note, that set size doesn't affect the image size, but only the size of the graph.
For very long labels you can rotate the text e.g. with set xtic rotate ....
Just set the offset:
set offsets <left>, <right>, <top>, <bottom>
you can also find the following commands useful:
unset offsets
show offsets
remember that offsets can be constant or an expression
also remember that offsets are ignored in splots.