Plot vectors only head with gnuplot - gnuplot

I need to plot only the vectors head, but using the following
plot 'plot.txt' u 1:2:($3*factor):($4*factor) w vector lc rgb 'black'
I obtain all the vectors. I only want the head.
so I need to delete a part of a vector mantaining only the head. How can I plot this?
Thank you.

The answer linked by #Christoph indeed contains the key ingredient:
The right command that you need is fixed which allows to plot only the head
However, one should be perhaps slightly more specific here. The keyword fixed per se does not produce "head-only arrows". Its primary purpose is to guarantee that the size of the arrows is independent of the length of the vectors. So in order to produce an arrow with its head only, one might merely shift the starting point of the arrow in the direction of the end point until it is "hidden" inside of the head. That's why the right inner-most arrow in this answer appears to be formed by its head only - the body (line) is just "covered" by the head.
So in order to do this in practice, one might proceed as:
reset
set terminal pngcairo
set output 'fig.png'
$db <<EOF
0.0 0.0 1 1
3.0 0.0 -1 1
3.0 3.0 -1 -1
0.0 3.0 1 -1
EOF
set xr [0:3]
set yr [0:3]
set size square
set xtics 0,1,3 in
set ytics 0,1,3 in
set mxtics 2
set mytics 2
unset key
set style arrow 1 head filled size screen 0.05,45 fixed lc rgb 'royalblue'
set style arrow 2 head filled size screen 0.05,45 fixed lc rgb 'dark-spring-green'
factor=0.5
sigma=0.99
plot \
$db using 1:2:(factor*$3):(factor*$4) with vectors as 2,\
$db using ($1+sigma*$3):($2+sigma*$4):((1-sigma)*$3):((1-sigma)*$4) with vectors as 1
The first part of the plot statement produces arrows (green) scaled with factor 0.5. Since their length is still significant, they appear with head as well as with the body. In the second part, there is the shift factor 0<=sigma<=1 - the statement ($1+sigma*$3):($2+sigma*$4):((1-sigma)*$3):((1-sigma)*$4) then requests an arrow with the same endpoint as before (for example, sum of the first and third columns is independent of sigma), but with shifted origin along the direction of the arrow (sigma=0 recovers original arrow, sigma=1 would produce zero-length arrow). Thus if sigma is sufficiently close to 1, only the arrow heads are visible:

Related

gnuplot pm3d and splot heat map with disorganised data

I used to make nice pm3d maps with gnuplot with a simple code like this:
set pm3d map
set palette
splot data using 1:2:3
But that had data organized as follows:
1 1 1
1 2 1
1 3 2
2 1 1
2 2 3
2 3 4
3 1 1
3 2 1
3 3 3
I never really understood the need for line break here but it worked. Now my data is quite different, the data in the first and second columns are not as simply repeated they are like this:
1.1 -1 2
1.2 3 3
1.11 4 4
...
I don't have any line breaks there since i have not idea how i should organise them. The question is, how would i make a heatmap from this? (rounding is not a good option)
Some sample data can be found here. They were created from an original 21x21 array (see below).
Some background
Originally, the data were in a table indexed by integers. It was basically a polar stereographic projection of the lunar surface. So i converted the indices to (x,y) distances then to planetocentric (latitude,longitude) pair and then to gnomonic polar coordinates recentered on a different point than one of the poles. I want to display the map as distance (x axis) and azimuth (y axis) (from the new centered point) and some value (the coloring of the map). The goal is to have something that looks like this:
The sample data you link to is highly structured, but not on an orthogonal grid. That is likely to produce artifacts. If the data were dense enough, you could simply draw each point as a solid block, perhaps with partial transparency. The example data you show is not very dense, however, so this is probably not suitable. I show such a plot below for reference.
set palette defined ( 0 "blue", 3 "green", 6 "yellow", 10 "red" )
set autoscale noextend
set pointsize 2
unset key
plot 'DT0C2.dat' using 1:2:3 with points pointtype 5 lc palette
The closest gnuplot has to dealing with unstructured sample is the dgrid3d mode. This basically uses the data points to assign value to nearby nodes on an orthogonal grid. Various weighting schemes are available to control how many data points contribute to each node and what is their relative contribution. The result is strongly dependent on choosing reasonable values for the orthogonal grid spacing and the weighting scheme. I won't attempt to describe all the options here. Please read the gnuplot documentation section on set dgrid3d. Here is a rough stab at it but I would want to understand the data a lot better to choose a good dgrid3d scheme. I think the sample data is not dense enough to produce a smooth result.
set palette defined ( 0 "blue", 3 "green", 6 "yellow", 10 "red" )
set autoscale noextend
set dgrid3d 75,75 gauss 100,25
set view map
splot 'DT0C2.dat' with pm3d

Gnuplot key: Force uneven split

I have four curves to plot. The first three are variants of each other, the fourth one is distinct. Hence, I would like the key to split in 3+1. However, using e.g.
set key maxrows 3
plot sin(x),sin(2*x),sin(3*x),exp(x)
gives a two-row key.
Can I force gnuplot to split the key in three+one?
In addition to #user8153's solution, I would like to suggest a slightly more general solution.
What if you have a colored background? For example: set term wxt background rgb "grey90" or if
you have a colored key (or legend) box... hmm, well, gnuplot doesn't offer an option for
colored background of the key box. Well, then if you put a colored rectangle behind the key.
Of course you can always adapt the color to the background, but I guess it would be simpler to plot an invisible line with lt -2 or lt nodraw.
About lt -2 or lt nodraw, I just learned a few days ago here: gnuplot: why is linewidth 0 not zero in width?. It's not (yet) in the manual, although it seems to be around since gnuplot version 5.0.
Code:
### invisible keyentry for column/row arrangement
reset session
set key top left maxrows 3
set obj 1 rect from graph 0.02,0.82 to graph 0.52,0.98 fs solid 1.0 fc rgb "grey90"
set xrange[-2:2]
set yrange[-2:2]
plot sin(x), sin(2*x), sin(3*x), exp(x), NaN lt -2 ti " "
### end of code
Result:
Addition:
Actually, I forgot that there is a workaround for a colored background of the keybox. No manual adjustment and fiddling around with the box:
Set custom background color for key in Gnuplot
In case you want a transparent background, e.g. for images on webpages using, e.g. pngcairo, pdfcairo, etc., besides lt -2 or lt nodraw, another solution would be to plot a transparent line, e.g. transparent "black" lc rgb 0xff000000:
plot sin(x), sin(2*x), sin(3*x), exp(x), NaN lc rgb 0xff000000 ti " "
Code:
### invisible keyentry for column/row arrangement with transparent background
reset session
set term pngcairo transparent
set output "tbKeyRows.png"
set key top left maxrows 3
set xrange[-2:2]
set yrange[-2:2]
plot sin(x), sin(2*x), sin(3*x), exp(x), NaN lt -2 ti " "
set output
### end of code
Result: (shown in front of checkerboard pattern)

How to remove line between "jumping" values, in gnuplot?

I would like to draw a line with plots that contain "jumping" values.
Here is an example: when we have plots of sin(x) for several cycles and plot it, unrealistic line will appear that go across from right to left (as shown in following figure).
One idea to avoid this might be using with linespoints (link), but I want to draw it without revising the original data file.
Do we have simple and robust solution for this problem?
Assuming that you are plotting a function, that is, for each x value there exists one and only one corresponding y value, the easiest way to achieve what you want is to use the smooth unique option. This smoothing routine will make the data monotonic in x, then plot it. When several y values exist for the same x value, the average will be used.
Example:
Data file:
0.5 0.5
1.0 1.5
1.5 0.5
0.5 0.5
Plotting without smoothing:
set xrange [0:2]
set yrange [0:2]
plot "data" w l
With smoothing:
plot "data" smooth unique
Edit: points are lost if this solution is used, so I suggest to improve my answer.
Here can be applied "conditional plotting". Suppose we have a file like this:
1 2
2 5
3 3
1 2
2 5
3 3
i.e. there is a backline between 3rd and 4th point.
plot "tmp.dat" u 1:2
Find minimum x value:
stats "tmp.dat" u 1:2
prev=STATS_min_x
Or find first x value:
prev=system("awk 'FNR == 1 {print $1}' tmp.dat")
Plot the line if current x value is greater than previous, or don't plot if it's less:
plot "tmp.dat" u ($0==0? prev:($1>prev? $1:1/0), prev=$1):2 w l
OK, it's not impossible, but the following is a ghastly hack. I really advise you add an empty line in your dataset at the breaks.
$dat << EOD
1 1
2 2
3 3
1 5
2 6
3 7
1 8
2 9
3 10
EOD
plot for [i=0:3] $dat us \
($0==0?j=0:j=j,llx=lx,lx=$1,llx>lx?j=j+1:j=j,i==j?$1:NaN):2 w lp notit
This plots your dataset three times (acually four, there is a small error in there. I guess i have to initialise all variables), counts how often the abscissa values "jump", and only plots datapoints if this counter j is equal to the plot counter i.
Check the help on the serial evaluation operator "a, b" and the ternary operator "a?b:c"
If you have data in a repetitive x-range where the corresponding y-values do not change, then #Miguel's smooth unique solution is certainly the easiest.
In a more general case, what if the x-range is repetitive but y-values are changing, e.g. like a noisy sin(x)?
Then compare two consecutive x-values x0 and x1, if x0>x1 then you have a "jump" and make the linecolor fully transparent, i.e. invisible, e.g. 0xff123456 (scheme 0xaarrggbb, check help colorspec). The same "trick" can be used when you want to interrupt a dataline which has a certain forward "jump" (see https://stackoverflow.com/a/72535613/7295599).
Minimal solution:
plot x1=NaN $Data u 1:2:(x0=x1,x1=$1,x0>x1?0xff123456:0x0000ff) w l lc rgb var
Script:
### plot "folded" data without connecting lines
reset session
# create some test data
set table $Data
plot [0:2*pi] for [i=1:4] '+' u 1:(sin(x)+rand(0)*0.5) w table
unset table
set xrange[0:2*pi]
set key noautotitle
set multiplot layout 1,2
plot $Data u 1:2 w l lc "red" ti "data as is"
plot x1=NaN $Data u 1:2:(x0=x1,x1=$1,x0>x1?0xff123456:0x0000ff) \
w l lc rgb var ti "\n\n\"Jumps\" removed\nwithout changing\ninput data"
unset multiplot
### end of script
Result:

Set title for arrow in gnuplot

I've used the arrow to draw a vertical line and I would like to title it so it's shown in the key. Is there a way to do it? As far as I can tell for the manual, there's no title option in the syntaxis for arrow, but I'm sure there's a workaround.
The only thing I think of is drawing the arrow with the same color as something outside the plot range and use its title, but it's rather clumsy.
I'm using the terminal pngcairo, just in case it's relevant.
You can plot something with vectors, which will give a title in the key. It plots arrows based on data points. The using statement is x:y:Δx:Δy where the tail is positioned at (x, y) and the head is at (x+Δx, y+Δy). For a vertical line, you can turn off the arrow head and use Δx of zero:
set terminal pngcairo dashed
set output 'plot.png'
set angles degrees
set xrange [0:360]
set yrange [-2:2]
plot sin(x), '-' using 1:(-2):(0):(4) with vectors nohead lc rgb 'black' title '90 degrees'
90
e
Gnuplot will ignore anything with an invalid value (1/0 for instance). You can take advantage of this to plot what you want.
Suppose that we set a vertical line with
set arrow from 1,graph 0 to 1,graph 1 nohead lt 0
Now, if I want this to be in the key, I can just plot a line with lt 0 but specify the y-value as 1/0. This will insert it in the key, but will not actually draw the line.
plot [-3:3] x**2 t "X Squared", 1/0 t "Vertical Line" lt 0

How do I use gnuplot to plot a simple 2d vector arrow?

This is my first time trying to use gnuplot, and I can't find any instructions on how to accomplish this. The closest I found was this:
http://gnuplot.sourceforge.net/docs_4.2/node259.html
plot 'file.dat' using 1:2:3:4 with vectors head filled lt 2
but I can't find any explanation about "file.dat".
So can somebody give a simple example of how to draw a simple 2d vector arrow? Thanks.
gnuplot has a very good help/documentation build in. Just type help plot or help vector to learn more on how to plot vectors in gnuplot.
The 2D vectors style draws a vector from (x,y) to (x+xdelta,y+ydelta).
A small arrowhead is drawn at the end of each vector.
4 columns: x y xdelta ydelta
This means, your input file should have 4 columns, where the first two columns define the starting (x,y)-position of the vector/arrow and the last two its (x,y) direction:
# file.dat
0 0 .5 .5
0 1 -.5 .5
1 1 1 0
Now typing the following command
plot "file.dat" using 1:2:3:4 with vectors filled head lw 3
gives the following output:
Drawing vectors with the set arrow command
Consider using the set arrow command, if you only need to draw a few vectors/arrows (e.g. to highlight some points in the plot).
set arrow 1 from pi/2,1 to pi/2,0
set arrow 2 from pi*3/2,-1 to pi*3/2,0
plot[0:2*pi] sin(x)
You can create 'file.dat' in a spreadsheet save it as text and put it in the path of gnuplot by using the cd command to point gnuplot to its location. If that does not agree with you, look at the examples using '+' and '++' and '-' in the gnuplot manual. These are a "virtual data file." Note that the first two are for one and two column data points i.e. (x) or (x,y). You will have to use $1 and $2 as variables for calculating dx and dy. It is obligatory to set the xrange and yrange variables and the isosamples for density for this to work.
Something like....
set isosamples 30
set samples 30
set xrange [-10:10]
set yrange [-10:10]
plot '++' using 1:2:(0.1*sin($1)):(0.1*cos($2)) with vectors

Resources