gnuplot: How to increase the width of my graph - gnuplot

I am using 'gnuplot' to plot a line graph with point:
set style data linespoints
set xlabel "number"
set ylabel "Dollars"
set yrange [0:250]
how can I increase the width of my graph, so that as I have more 'x', i want my graph to more of a rectangle instead of a square?
And how can I increase the interval of my 'y-axis'? now, it just draw a mark for every 50 in my y axis?

It sounds like you want your output to dynamically adjust in size to the data being plotted. Here is a script that does that:
#!/usr/bin/env gnuplot
# don't make any output just yet
set terminal unknown
# plot the data file to get information on ranges
plot 'data.dat' title 'My Moneys'
# span of data in x and y
xspan = GPVAL_DATA_X_MAX - GPVAL_DATA_X_MIN
yspan = GPVAL_DATA_Y_MAX - GPVAL_DATA_Y_MIN
# define the values in x and y you want to be one 'equivalent:'
# that is, xequiv units in x and yequiv units in y will make a square plot
xequiv = 100
yequiv = 250
# aspect ratio of plot
ar = yspan/xspan * xequiv/yequiv
# dimension of plot in x and y (pixels)
# for constant height make ydim constant
ydim = 200
xdim = 200/ar
# set the y tic interval
set ytics 100
# set the x and y ranges
set xrange [GPVAL_DATA_X_MIN:GPVAL_DATA_X_MAX]
set yrange [GPVAL_DATA_Y_MIN:GPVAL_DATA_Y_MAX]
# set the labels
set title 'Dollars in buckets'
set xlabel 'number'
set ylabel 'Dollars'
set terminal png size xdim,ydim
set output 'test.png'
set size ratio ar
set style data linespoints
replot
For these example data:
0 50
50 150
100 400
150 500
200 300
I get the following plot:
It is about square, as it should be (I defined 100 units in x to be equal to 250 units in y, and the data span the range [(0,200),(50,500)]). If I add another data point (400,300), the output file is wider, as expected:
To answer your other question, you can set the y tic increment thus:
set ytics <INCREMENT>
The script above gives an example.

To add to the discussion here, there's also set size ratio ... so that you can set the aspect ratio of your plot.
Here's an excerpt from help set size:
ratio causes gnuplot to try to create a graph with an aspect ratio of
(the ratio of the y-axis length to the x-axis length) within the portion of
the plot specified by <xscale> and <yscale>.
The meaning of a negative value for is different. If =-1, gnuplot
tries to set the scales so that the unit has the same length on both the x
and y axes (suitable for geographical data, for instance). If =-2, the
unit on y has twice the length of the unit on x, and so on.
For this to really work, you'll probably need to set the output driver to some reasonable size:
set term png size 800,400 #800 pixels by 400 pixels
or:
set term post size 8,4 #8 inches by 4 inches
This is all terminal dependent, so its worth it to look up the terminal's help to see what units it uses, etc.

set xrange[:]
set yrange[:]
Use those 2 commands to define the 'size' of your graph ;)

Related

gnuplot histogram bins divided by volume

I am simulating points in a sphere volume with radius 1. I generated 1.000.000 monte-carlo based points in this volume. To make a gnuplot histogram i calculated the length of each vector (every vector length is between 0 and 1). With 100 bins the histogram looks like:
gnuplot data histogram.
If someone is wondering why there no points greater than 0.91 are generated, i also dont know, but this is not the question here.
This is my gnuplot Code:
n=100 #number of intervals
max=1.0 #max value
min=0.0 #min value
width=(max-min)/n #interval width
#function used to map a value to the intervals
hist(x,width)=width*floor(x/width)+width/2.0
#settings
set xlabel "Radius"
set ylabel "Primarys/Intervall"
set xrange [-0.1:1.1]
set yrange [0:32000]
set boxwidth width*0.8
set style fill solid 0.5 #fillstyle
set tics out nomirror
#plot
plot "primaryPosition(1).csv" u (hist($1,width)):(1.0) smooth freq w boxes lc rgb"green"
In general: A Volume grows by r^3 to Radius r.
In my histrogram every spherical shell is one bin and the bin number is 100. So, as the bin number increases, the volume of each sperical shell grows cubically (with r^3). From this point of view, the histogram looks good.
But what i want to do is to plot the density of points per volume: points/shellvolume.
This should be a linear distribution from the center of the sphere to its border.
How can i tell gnuplot to divide each bin by its corresponding volume, which depends on the outer and the inner radius of each spherical shell?
The formula is: (4/3)pi(R^3-r^3) with R outer and r inner radius a shell.
The following example creates some random test data (should be 20'000 equally distributed random points).
One possibility would be that you first you create your histogram data via binning into a table and then you divide it by the volume of the shell.
By the way, the volume of a sphere shell is (4./3)*pi*(R**3-r**3), not the formula you've given. And why are you setting max < min? Maybe you want to fine tune the binning to your exact needs.
Code:
### histogram normalized by sphere shell volume
reset session
set view equal xyz
# create some test data
set print $Data
do for [i=1:20000] {
x = rand(0)*2-1
y = rand(0)*2-1
z = rand(0)*2-1
r = sqrt(x**2 + y**2 + z**2)
if (r <= 1) { print sprintf("%g %g %g %g",x,y,z,r) }
}
set print
n = 100 # number of intervals
min = 0.0 # max value
max = 1.0 # min value
myWidth=(max-min)/n # interval width
bin(x)=myWidth*floor(x/myWidth)
ShellVolume(r) = (4./3)*pi*((r+myWidth)**3-r**3)
set boxwidth myWidth absolute
set table $Histo
plot $Data u (bin($4)):(1) smooth freq
unset table
set multiplot layout 2,1
plot $Histo u 1:2 w boxes ti "Occurrences"
plot $Histo u 1:($2/ShellVolume($1)) w boxes ti "Density"
unset multiplot
### end of code
Result:

How can I make a filled region in the x direction in gnuplot?

I know that gnuplot has the great type of plot that is filledcurve, which you can make a filled region between two curves that are presented like 1:2:3, it will make a curve between columns $2 and $3 for the same x value $1. But how can I fill this region in the graph below in gnuplot? The range is in x direction like x1:x2:y, same value of y.
My data it's in form like:
# rho1 rho2 C
0.8022651311239721 0.8299444680667378 0.00005011872336272725
0.8022624676512962 0.8299464715046031 0.00004466835921509635
0.8022618998639025 0.8299490455369624 0.000039810717055349695
0.8022533810411624 0.8299390462160209 0.000035481338923357534
...
But I can separate that in two archives too.
Here is a useful trick that uses the 3D plotting style with zerror and then sets the view angle so that it looks like a 2D x/y plot. I don't have enough of your data to replicate the plot you show so I use a junk data file just for the purpose of showing how the plot works:
# 3D plot style "with zerror" takes 5 columns of input
# x y z zlow zhigh
# We will choose a view angle such that "z/zlow/zhigh" is the horizontal axis
# "x" is the vertical axis
# "y" is unused because it is along the line of sight
# For your data as described
rho1 = 1 # column 1
rho2 = 2 # column 2
c = 3 # nominal y value, we use it for X
junk = 0 # unused constant coordinate
rhomean(c) = (column(rho1) + column(rho2)) / 2.
set view 270, 0
set view azimuth -90
unset ytics
set zlabel "ρ" # horizontal axis in this projection
set xlabel "C" # vertical axis in this projection
set zrange [0:50] # Note how this affects the horizontal axis!
splot "data" using c:(junk):(rhomean(c)):rho1:rho2 with zerror lt black fc "gold"
The with zerror plot style and the set view azimuth command both require a reasonbly current version of gnuplot.

Gnuplot: power notation axis

I set the y-axis in power notation (1.0e+5 or 1.0 * 1.0^5) but I would like to report the power just on top of the axis to save space. In particular I would like to report at the end of the axis as reported in the link
Try use this commented code:
# Creating some 'x y' data to plot and
# save output using 'table' and
# datablock named 'data'
set table $data
plot (1E-5 + sin(x)*1E-5)
unset table
# Performs statistics using 'y' column
# to find max value, turn off output, and
# set prefix name 'data' to stats results
stats $data u 2 nooutput name 'data'
set tmargin at screen 0.94 # Change the top margin
# Define a label containing the power to base 10
# of max value from data and put on top-left
# using the same value of top margin
# but using offset on y axis
set label gprintf('×10^{%T}',data_max) at graph 0.0, screen 0.94 offset 0,0.75
set format y '%.2t' # Format for 'y' values using mantissa
# to base 10 and 2 decimal places
set xlabel 't' # label to 'x' axis
set ylabel 'Ω' # label to 'y' axis
unset key # Turn off key (legend)
set tics nomirror # Turn off upper and right tic marks
# The plot itself
plot $data using 1:2 w l
Produces
I guess is very common to put the prefactor in the label (instead of top of the axis). If you absolutely need it on top, let me know. One way would be the following. There would also be ways to determine the prefactor automatically.
Code:
### prefactor for axis
reset session
Power = 5
set format y "%.2f"
set ylabel sprintf("Ω [10^%d rpm]", Power) enhanced
f(x) = 3e4*sin(x)+1.2e5
plot f(x)/10**Power w l notitle
### end of code
Result:

How to make dashed grid lines intersect making crosshairs in gnuplot?

I'm plotting some data and I want to use dashed grid lines.
Any dashed grid line would suffice, but I prefer a "long dash, short dash, long dash" format.
For example, given the following code
set grid lc rgb "#000000" lt 1 dt (50, 25, 20, 25)
plot x**2
I get this result
But I would rather the grid lines intersection to happen always at the middle of two dashes, like this
If I could make horizontal grid lines different to vertical grid lines and I could add some offset to each one, then I'd imagine there's a way to accomplish this. But I can't seem to do that either.
It looks like gnuplot cannot have two different dashstyles for x-grid and y-grid.
One workaround I see currently is to plot two identical plot on top of each other. One with appropriate x-grid lines and the other with appropriate y-grid lines.
If you want a dash pattern with proportions of (50-25-20-25), this correspond to (25-25-20-25-25-0) or (5-5-4-5-5-0) between two tics.
Furthermore, the dash and gap length numbers, e.g. in dt (50,25,20,25), seem to be in a fixed relation to the graph size. The "empirical" factor is 11 with good approximation (at least for the wxt terminal which I tested under gnuplot 5.2.6).
Edit: actually, the code below gives different results with a qt terminal. And it's not just a different factor. It's more complicated and probably difficult to solve without insight into the source code. So, the fact that the following seems to work with wxt terminal (maybe even just under Windows?) was probably a lucky strike.
With this you can create your dash lines automatically resulting in crosshairs at the intersections of the major grid lines.
Assumptions are:
your first and last tics are on the borders
you know the number of x- and y-intervals
You also need to know the graph size. These values are stored in the variables GPVAL_TERM..., but only after plotting. That's why you have to replot to get the correct values.
This workaround at least should give always crosshairs at the intersection of the major grid lines.
Edit 2: just for "completeness". The factors to get the same (or similar) looking custom dashed pattern on different terminals varies considerably. wxt approx. 11, qt approx. 5.6, pngcairoapprox. 0.25. This is not what I would expect. Furthermore, it looks like the factors slightly depend on x and y as well as graph size. In order to get "exact" crosshairs you might have to tweak these numbers a little further.
Code:
### dashed grid lines with crosshairs at intersections
reset session
TERM = "wxt" # choose terminal
if (TERM eq "wxt") {
set term wxt size 800,600
FactorX = 11. # wxt
FactorY = 11. # wxt
}
if (TERM eq "qt") {
set term qt size 800,600
FactorX = 5.58 # qt
FactorY = 5.575 # qt
}
if (TERM eq "pngcairo") {
set term pngcairo size 800,600
set output "tbDashTest.png"
FactorX = 0.249 # pngcairo
FactorY = 0.251 # pngcairo
}
set multiplot
set ticscale 0,0
Units = 24 # pattern (5,5,4,5,5,0) are 24 units
# set interval and repetition parameters
IntervalsY = 10
RepetitionsY = 1
IntervalsX = 4
RepetitionsX = 3
# initial plot to get graph size
plot x**2
gX = real(GPVAL_TERM_YMAX-GPVAL_TERM_YMIN)/IntervalsY/Units/FactorY/RepetitionsY
gY = real(GPVAL_TERM_XMAX-GPVAL_TERM_XMIN)/IntervalsX/Units/FactorX/RepetitionsX
# first plot with x-grid lines
set grid xtics lt 1 lc rgb "black" dt (gX*5,gX*5,gX*4,gX*5,gX*5,0)
replot
unset grid
# second plot with y-grid lines
set grid ytics lt 1 lc rgb "black" dt (gY*5,gY*5,gY*4,gY*5,gY*5,0)
replot
unset multiplot
set output
### end of code
Result:
Not really. The closest I can think of is
set grid x y mx my
set grid lt -1 lc "black" lw 1 , lt -1 lc bgnd lw 16
set ticscale 1.0, 0.01
set mxtics 4
plot x**2 lw 2
But that leaves the vertical grid lines solid.

Centering bins in Gnuplot Histogram

In gnuplot, you can create a histogram like
binwidth=#whatever#
set boxwidth binwidth
bin(x,width)=width*floor(x/width)+binwidth/2.0
plot "gaussian.data" u (bin($1,binwidth)):(1.0/10000) smooth freq w boxes
Currently, my bins seem to be centered on the right-edge. That is, the bin corresponding to x=0 has its right edge above zero. I would like to have the bins center-oriented. That is, I would like to have the center of each bin above the corresponding x values. I have tried messing with the arguments of bin(x,width) but haven't been successful. Any suggestions?
bin(x,width) = width*round(x/width)
should do the trick. You can simply visualize how the binning works:
binwidth = 0.5
round(x) = floor(x+0.5)
bin(x,width) = width*round(x/width)
set xrange [-2:2]
set xlabel "x"
set ylabel "bin position"
set grid
plot bin(x,binwidth)
gives
Note that values in [-0.25,0.25] are mapped to the bin at position 0, values in [0.25, 0.75] are mapped to the bin at position 0.5, and so forth.

Resources