I am trying to draw 3d vectors from two different files to color the vectors in the first file with black and the others with red. Does anyone have an idea about how to achieve that?
This is a pretty easy one.
First set up your arrow styles:
set style arrow 1 linecolor rgb "red"
set style arrow 2 linecolor rgb "black"
Now make your plots:
splot 'datafile1' u 1:2:3:4:5:6 with vectors arrowstyle 1, \
'datafile2' u 1:2:3:4:5:6 with vectors arrowstyle 2
Of course, this assumes your datafiles are set up as:
x1 y1 z1 dx1 dy1 dz1
x2 y2 z2 dx2 dy2 dz2
...
Related
I would like to plot a 3D vector field in gnuplot where every vector is a specified color. My input file looks like this:
x
y
z
dx
dy
dz
color
x1
y1
z1
dx1
dy1
dz1
color1 (hex code)
and so forth. I tried the following code, piggybacking off the solution*
scale = 1
splot 'file.dat' u 1:2:3:($4*scale):($5*scale):($6*scale):7 w vectors arrowstyle 1 lc rgb var
but this gave me a color bar on the side of the graph. Also, every vector was colored gray, instead of the color in the input file. Could someone suggest a fix for this?
* Vector field 3D plot in gnuplot with contour of vectors (bottom)
Your command is very nearly correct. The problem is that apparently the line color is considered part of the arrow style, so the program produces an error message duplicated or contradicting arguments in plot options if you give both an arrow style and a line color. If you move the lc rgb variable to the style definition, it is accepted. This works for me:
set style arrow 1 filled head lc rgb variable
plot DATA using 1:2:3:4:5:6:7 with vectors arrowstyle 1
I haven't been able to find any example of what I'm trying to do in GNUplot from raking docs and demos.
Essentially I want to plot the Blue, Green, and Red lines I manually drew on this output (for demonstration) at the 10/50/90% marks.
EDIT: For clarity, I'm looking to determine where the distribution lines hit the cumulative distribution at 0.1/0.5/0.9 to know which co-ordinates to draw the lines at. Thanks!
set terminal png size 1600,800 font "Consolas" 16
set output "test.png"
set title "PDF and CDF - 1000 Simulations"
set grid y2
set ylabel "Date Probability"
set y2range [0:1.00]
set y2tics 0.1
set y2label "Cumulative Distribution"
set xtics rotate by 90 offset 0,-5
set bmargin 6
plot "data.txt" using 1:3:xtic(2) notitle with boxes axes x1y1,'' using 1:4 notitle with linespoints axes x1y2
Depending on the number of points in your cumulative data curve you might need interpolation. The following example is chosen such that no original data point will be at your levels 10%, 50%, 90%. If your data is not steadily increasing, it will take the last value which matches your level(s).
The procedure is as follows:
plot your data to a dummy table.
check when Level is between to successive y-values (y0,y1).
remember the interpolated x-value in xp.
draw arrows from the borders of the graph to the point (xp,Level) (or instead use the partly outside rectangle "trick" from #Ethan).
Code:
### linear interpolation of data
reset session
set colorsequence classic
set key left
# create some dummy data
set sample 10
set table $Data
plot [-2:2] '+' u 1:(norm(x)) with table
unset table
Interpolate(yi) = x0 + (x1-x0)*(yi-y0)/(y1-y0)
Levels = "0.1 0.5 0.9"
do for [i=1:words(Levels)] {
Level = word(Levels,i)
x0 = x1 = y0 = y1 = NaN
set table $Dummy
plot $Data u (x0=x1,x1=$1,y0=y1,y1=$2, (y0<=Level && Level<=y1)? (xp=Interpolate(Level)):NaN ): (Level) w table
unset table
set arrow i*2 from xp, graph 0 to xp,Level nohead lc i
set arrow i*2+1 from xp,Level to graph 1,Level nohead lc i
}
plot $Data u 1:2 w lp pt 7 lc 0 t "Original data"
### end code
Result:
It is not clear if you are asking how to find the x-coordinates at which your cumulative distribution line hits 0.1, 0.5, 0.9 (hard to do so I will leave that for now) or asking how to draw the lines once you know those x values. The latter part is easy. Think of the lines you want to draw as the unclipped portion of a rectangle that extends off the plot to the lower right:
set object 1 rectangle from x1, 0.1 to graph 2, -2 fillstyle empty border lc "blue"
set object 2 rectangle from x2, 0.1 to graph 2, -2 fillstyle empty border lc "green"
set object 3 rectangle from x3, 0.1 to graph 2, -2 fillstyle empty border lc "red"
plot ...
I have a dataset that defines two curves, and I want to fill the area between them. However, contrary to the standard situation, the abscissa is to be plotted on the vertical axis and the ordinates on the horizontal one; the abscissa indicates depth, this is a common plotting format in geophysics. In other words, I want something like
plot 's.dat' u 1:2:3 w filledcurves
but with swapped axes so that the filled area is bounded not at the top and bottom but to the left and right by the curves as seen in
plot 's.dat' u 2:1,'s.dat' u 3:1
My dataset is like this:
0. -1.776 -0.880
160. -1.775 -0.882
160. -1.692 -0.799
320. -1.692 -0.800
320. -1.531 -0.634
480. -1.534 -0.637
480. -1.286 -0.394
Is this possible in Gnuplot?
Thomas
This is a totally different solution using 3D plot style "with zerror".
You will need current gnuplot (version 5.2) for this. The plot style was really not designed for this so there are some difficulties (e.g. x tic marks invisible because drawn perpendicular to the plane of the plot, all tic labels requiring an offset for readability).
#
# [mis]use 3D plot style "with zerror" to create a plot of the xz
# plane with area fill between two sets of data points with
# equal coordinates on the vertical axis (x) but contrasting
# values on the horizontal axis (z).
#
set view 270, 0
set view azimuth -90
set xyplane at 0
unset ytics
set ztics offset 4, -2 out
set xtics offset 4
splot 's.dat' using 1:(0):(0.5*($2+$3)):2:3 with zerror notitle
If there is some value of x which is guaranteed to lie between the two curves then you can plot in two halves. For the data you show, x=-1 would be a suitable value and the plot command would be:
plot 's.dat' u 2:1 with filledcurve x=-1 lt 3, \
's.dat' u 3:1 with filledcurve x=-1 lt 3
If the requirement for a constant intermediate x value can only be
satisfied piece-wise, e.g.
x=-1 for (0<y<500), x=0 for (500<y<1000)
then it may nevertheless be possible to construct a graph by stacking
the piecewise sections.
A simple way would be to define a closed line and fill it. For this, you take column 2 and add the reversed column 3. You probably need gnuplot >=5.2 for this.
Code:
### fill between vertical curves
reset session
$Data <<EOD
0. -1.776 -0.880
160. -1.775 -0.882
160. -1.692 -0.799
320. -1.692 -0.800
320. -1.531 -0.634
480. -1.534 -0.637
480. -1.286 -0.394
EOD
set print $Outline
do for [i=1:|$Data|] {
print sprintf("%s %s", word($Data[i],2), word($Data[i],1))
}
do for [i=|$Data|:1:-1] {
print sprintf("%s %s", word($Data[i],3), word($Data[i],1))
}
set print
plot $Outline w filledcurve lc rgb "green"
### end of code
Result:
I am having some difficulty generating a plot of a data set that is oscillating between negative and positive values (line a sin or cos). My goal is to fill the area under the curve with alternating colour: negative region with blue and positive with red. To be more precise I want to fill the area between the curve and the x axis. So far i managed to plot the curve with alternating colours (blue for negative, red for positive) using:
set palette model RGB defined ( 0 'red', 1 'blue' )
unset colorbox
plot 'data.set' u 1:2:( $2 < 0.0 ? 1 : 0 ) w lines lt 1 lw 4 palette
Unfortunately if I replace w lines with filledcurves I don't get an alternate fill. How can one accomplish this?
Cheers
If I understood the question correctly, you can try this:
plot '+' using 1:(0):(sin($1)) w filledc below, \
'+' using 1:(0):(sin($1)) w filledc above
which is telling gnuplot to fill the area between two curves (sin(x) and 0), using the above and below positions. There is another solution as well:
plot '+' using 1:(sin($1) > 0 ? sin($1):0) w filledcurves y1, \
'+' using 1:(sin($1) < 0 ? sin($1):0) w filledcurves y2
and the result would be:
The important part refers to the options part of filledcurves. See more details here and here.
How can I plot an image with partially transparent scatter points, just like in the picture below, with Gnuplot? The problem is that I don’t know how to set the points to be transparent.
Try this:
set style fill transparent solid 0.35 noborder
set style circle radius 0.02
plot 'test' u 1:2 with circles lc rgb "blue", \
'' u 1:2 every 100 w circles lc rgb "red" fs solid 1.0 border lt -1
which outputs
As you can see, you can specify for each data set whether to use transparency and which color to use.
If your data consist of two values (x and y position of the circle) you have to specify the circle's radius via set style circle .... If your data has three rows, you can use the third value to specify the circle's radius for each data point.
You can play with the transparency level, which ranges from 0 (full transparency) to 1 (no transparency).
You can use the alpha channel of argb along with lc rgb variable:
set samp 2000
randn(x) = invnorm(rand(x))
pl [-3:3][-3:3] '+' us (randn(0)):(randn(0)):(0xBB00AAFF) lc rgb variable pt 7 ps 2
.
This leaves some egde around each circle, probably an opacity effect from a circle plus a filled circle on top of it. Unfortunately, there is no edgecolor option as in matplotlib to control this. Replacing filled circles pt 7 with open circles but thick linewidth pt 6 lw 6 can mitigate this a bit
pl [-3:3][-3:3] '+' us (randn(0)):(randn(0)):(0xBB00AAFF) lc rgb variable pt 6 lw 6
.
One can also emulate a variable transparency with lc rgb variable
set samp 50
pl '+' us 1:1:(0x00AAFF+(int(0xFF*$1/10.)<<24)) pt 7 lc rgb variable ps 3
where int(0xFF*$1/10.) maps the input from 0..10 into 0..255 and <<24 shifts it into the alpha channel.
Note that in your plot only the dense regions seem to have a transparency effect, but not the scatter points in the background.