Related
I'm using software that uses Gnuplot language to plot some data, but I've never used Gnuplot before.
So I was trying to place labels and rectangles in a way that created a nice and readable text, which wasn't bad (as you can see with the number 182 in the image below), but I wanted to learn how to rotate the rectangle and label so that they line up with the white line.
(I can't post images, but it's like that in this link Right now, it looks like:
)
I've already learned to rotate the label (as you can see the number 171), but apparently, it doesn't work the same way with the object.
# setting the label and rotating it works
set label 1 "TEXT" at 10, 20 center rotate by 30 front
# setting the object works
set object 1 rect center 10,20 size 1,2 front
# But this doesn't work
set object 1 rect center 10,20 size 1,2 rotate by 30 front
# this line return the error message "Unrecognized or duplicate option"
The important part of my code that sets a rectangle and a label is here below:
x1 = 2979
x2 = 3140
y1 = -225
y2 = -168
ang = 19.9275
h = 30
w = 60
# set object 1 rect center (x1+x2)/2,(y1+y2)/2 size w,h rotate by ang front fillcolor "black" fillstyle transparent solid 0.5 noborder
set object 1 rect center (x1+x2)/2,(y1+y2)/2 size w,h front fillcolor "black" fillstyle transparent solid 0.5 noborder
set label 1 sprintf("{/:Bold %1.0f}",sqrt((x2-x1)**2 + (y2-y1)**2)) at (x1+x2)/2,(y1+y2)/2 center rotate by ang front tc rgb "white"
set arrow from x1,y1 to x2,y2 heads size 10,90 front linecolor rgb "white" linewidth 2.5 dashtype 6
So how do I rotate the rect object? And if it's not possible, is there another way to do this (other than having to manually set a polygon)?
Check the following example and help labels.
You can create a datablock and add your labels and plot them rotated and boxed together with your map.
Edit: ...forgot the semitransparent boxes. You need to play with the alpha channel, i.e. 0xAARRGGBB.
Code:
### boxed semitransparent text labels
reset session
# create some background test data
f(x,y)=(sin(1.3*x)*cos(.9*y)+cos(.8*x)*sin(1.9*y)+cos(y*.2*x))*3+15
set samples 51
set isosamples 51
set table $Data
splot [0:600][0:600] f(x/60.,y/60.)
unset table
$myLabels <<EOD
# text x y a
171 300 300 45
182 100 500 90
197 500 400 60
333 400 100 -30
EOD
set style fill transparent solid 1.0 noborder
set style textbox opaque fc rgb 0xaaffffff noborder
set angle degrees
set key noautotitle
plot $Data u 1:2:3 with image palette,\
$myLabels u 2:3:1:4 w labels rotate var boxed font ",24"
### end of code
Result:
I am plotting a curve in gnuplot. I would like to call out a couple of specific points on the curve.
This is what the curve looks like:
Shown below is what I'm hoping to get (but I had to draw in the points and lines to the axes with GIMP). I'd like to call out two specific points on the curve. The first, where Vgs (x-axis) equals -0.5. The second, where Id (y-axis) equals 2.5. If possible, I'd like to also have a dashed line over to the axis to aid in reading the values.
I found a reference that said to try plotting a circle using set object circle and the coordinates, but I must not have it right, because it complains about extra parameters. Browsing the manual is so far unsuccessful. I'm not even sure what term to search for.
Is there an easy way to call out a couple of points on the curve that I've drawn and have it look similar to the screenshot below?
Here are the commands I used to plot the curve:
set xlabel "Vgs (Volts)"
set ylabel "Id (mA)"
set grid
Idss=5
Vgs_off=-1
Id(Vgs) = Idss * (1 - (Vgs / Vgs_off) ) ** 2
plot [Vgs=Vgs_off:0][0:Idss + 1] Id(Vgs)
It's the characteristic curve for a Fairchild J112 JFET if anyone is curious.
Edited to replace the -1 in the denominator with Vgs_off to avoid confusion. This is a value from the JFET's datasheet and just happened to be -1 in this particular case.
ADDENDUM:
After incorporating the pieces from the answer given by #Eldrad, I came up with this much improved representation of the JFET characteristic curve:
Here are the commands used to create it:
# JFET parameters from data sheet
Vgs_off=-1
Idss=5
# JFET characteristic curve
Id(Vgs) = Idss * (1 - (Vgs / Vgs_off) ) ** 2
# Graph properties
set title "I_D vs V_{GS}"
set xlabel "V_{GS} (Volts)"
set ylabel "I_D (mA)"
set grid
set key off
set monochrome
# Plot the characteristic curve
plot [Vgs=Vgs_off:0][0:Idss] Id(Vgs)
# Plot interesting points
set object circle center 0.5 * Vgs_off, Id(0.5 * Vgs_off) radius char 0.33 fillstyle solid fillcolor rgb 'black'
set object circle center 0.293 * Vgs_off, Id(0.293 * Vgs_off) radius char 0.33 fillstyle solid fillcolor rgb 'black'
# Mark interesting points with dashed lines to where they intersect the x and y axes.
set arrow from first 0.5 * Vgs_off, graph 0 to first 0.5 * Vgs_off, graph 1 dashtype "-" nohead
set arrow from graph 0, first Id(0.5 * Vgs_off) to graph 1, first Id(0.5 * Vgs_off) dashtype "-" nohead
set arrow from 0.293 * Vgs_off, graph 0 to 0.293 * Vgs_off, graph 1 dashtype "_" nohead
set arrow from graph 0, first Id(0.293 * Vgs_off) to graph 1, first Id(0.293 * Vgs_off) dashtype "_" nohead
# Label the lines
set label "I_{DSS}" at graph 1.01, graph 1
set label "I_{DSS} / 2" at graph 1.01, graph 0.50
set label "I_{DSS} / 4" at graph 1.01, graph 0.25
set rmargin at screen 0.9
# Update the graph
replot
Getting specific values of a function is straightforward if the function y=f(x) and its inverse x=f(y) have an analytical expression, like it is in your case.
A couple of remarks about your function definition: You should use x as the variable, because this is the default gnuplot is looking for, it also makes the plot command shorter. Also, division by -1 is the same as putting a minus in front, so an easier function definition, including the inverse would be:
Idss = 5.0
Id (x) = Idss * (1 + x)**2
Id_inv (x) = sqrt(x/Idss) -1
Now the dashed lines can be drawn as arrows (check set arrow):
set arrow 11 from first -0.5, graph 0 to first -0.5, first Id(-0.5) lc "red" lw 2 dt 2 nohead
set arrow 12 from first -0.5, Id(-0.5) to graph 0, first Id(-0.5) lc "red" lw 2 dt 2 nohead
set arrow 21 from first Id_inv(2.5), graph 0 to Id_inv(2.5), 2.5 lc "green" lw 2 dt 2 nohead
set arrow 22 from first Id_inv(2.5), 2.5 to graph 0, first 2.5 lc "green" lw 2 dt 2 nohead
I would recommend drawing the horizontal lines to the axis where the tics are actually printed (i.e. to the left side). The reference points are the x- or y-values of the function and the border of the graphs, see the manual about coordinates for a detailed explanation.
You could add specific tic marks at those points:
set xtics add (-0.5, Id_inv(2.5))
set ytics add (Id(-0.5), 2.5)
You also asked about points in your comment and got the correct approach. The size of the circle can be chosen in any coordinate system (I think character is the width of a letter – x? – in the current font, but I'm not 100% sure)
set object 1 circle center -0.5,Id(-0.5) radius first 0.01 fs solid noborder fc "red"
set object 2 circle center Id_inv(2.5),2.5 radius first 0.01 fs solid noborder fc "green"
Now the remaining decoration can be added:
set title "{/:Italic I}_d vs {/:Italic V}_{gs}"
set xlabel "{/:Italic V}_{gs} /V"
set ylabel "{/:Italic I}_d /mA"
set xrange [-1:0]
plot Id(x)
I am trying to create an object, a rectangle from the bottom of the x axis (15,32) right to the top. It should be an easy task and I have tried various coordinates but I dont seem to be able to do it right. Can anyone help?
> set palette defined ( -1.0 "blue",\
> -0.5 "light-blue",\
> 0 "white",\
> 0.5 "light-red",\
> 1.0 "red")
> set cbrange [ 1.000: -1.000] set pm3d map corners2color c2 set ytics (1.000, 50.00, 100.00, 150.00,
> 200.00, 250.00, 300.00, 350.00, 400.00, 450.00, 500.00, 550.00, 600.00, 650.00, 700.00, 750.00, 800.00, 850.00, 900.00, 924.00) set xtics (1.000, 50.00, 100.00, 150.00, 200.00, 250.00, 300.00,
> 350.00, 400.00, 450.00, 500.00, 550.00, 600.00, 650.00, 700.00, 750.00, 800.00, 850.00, 900.00, 924.00) set xlabel "Residue" set ylabel "Residue" set yrange [ 0.000: 926.000] set xrange [ 0.000:
> 926.000] set object 1 rectangle from 1,308 to 308,1 front fs empty border rgb "black" set object 2 rectangle from 309,616 to 616,309
> front fs empty border rgb "black" set object 3 rectangle from 617,924
> to 924,617 front fs empty border rgb "black" set obj rect from 1,
> graph 15 to 32, graph 1 front fs empty border rgb "black"
Would be great if anyone can help
Please have a look at the manual or in gnuplot console type help coordinates.
I assume you want a rectangle from x=15, bottom graph border to x=32, top graph border.
set object 4 rect from first 15, graph 0 to first 32, graph 1
or since default coordinate system is first, a bit shorter
set object 4 rect from 15, graph 0 to 32, graph 1
I would like to plot the positive and negative values of a non-equidistant matrix with different palettes (each a logscale), such that the overall effective color code is (-max "blue", <1e-6 "white", max "red"). In order to do that it is required to use multiplot for each plot and overlay them perfectly. The problem is now, that the complement values, which should be "NaNs", are plotted as white and not transparent (please see figure). As a result, the latter plot completely overlays the former, which cannot be seen. I tried to define my own color palette with transparent colors, but cannot make it work with the "plot for" command. (Remark: This is a follow-up question from here.)
Current plotscript:
CoordsX = "0.04 0.11 0.24 0.4 0.51"
CoordsY = "0.04 0.11 0.24 0.4 0.51"
dim_x = words(CoordsX)
dim_y = words(CoordsY)
dx(i) = (word(CoordsX,i)-word(CoordsX,i-1))*0.5
dy(i) = (word(CoordsY,i)-word(CoordsY,i-1))*0.5
ndx(i,j) = word(CoordsX,i) - (i-1<1 ? dx(i+1) : dx(i))
pdx(i,j) = word(CoordsX,i) + (i+1>dim_x ? dx(i) : dx(i+1))
ndy(i,j) = word(CoordsY,j) - (j-1<1 ? dy(j+1) : dy(j))
pdy(i,j) = word(CoordsY,j) + (j+1>dim_y ? dy(j) : dy(j+1))
set size square
set xrange[ndx(1,1):pdx(dim_x,1)]
set yrange[ndy(1,1):pdy(1,dim_y)] reverse
set tic out
set term png truecolor
set output "test.png"
set multiplot
max = 25
set cbrange [0:max]
set object rectangle from screen 0,0 to screen 1,1 behind fillcolor rgb "grey" fillstyle solid noborder # Only added to see transparency
set palette defined (0 "white", max "blue")
plot for [i=1:dim_x] file u\
(real(word(CoordsX,i))):1:(ndx(i,int($0))):(pdx(i,int($0))):(ndy(i,int($0+1))):(pdy(i,int($0+1))):(column(i)<0?abs(column(i)):NaN)\
with boxxyerror fs transparent solid 1.0 palette notitle
set palette defined (0 "white", max "red")
plot for [i=1:dim_x] file u\
(real(word(CoordsX,i))):1:(ndx(i,int($0))):(pdx(i,int($0))):(ndy(i,int($0+1))):(pdy(i,int($0+1))):(column(i)>0?abs(column(i)):NaN)\
with boxxyerror fs transparent solid 1.0 palette notitle
unset multiplot
set output
A few comments:
1) multiplot is not the right mechanism to create a single plot. You will get better results by reorganizing your command sequence into a single plot command. If necessary you can split your palette into two halves, a red half and a blue half. E.g.
set palette defined (0 "white", 1 "dark-red", 1 "white", 2 "dark blue")
set cbrange [0 : 2*max]
plot 'redstuff' using 1:...:(color) fc palette, \
'bluestuff' using 1:...:(color+max) fc palette
2) The fill style you selected is fully opaque. If you want 50% transparency it needs to be
set style fill transparent solid 0.5
3) It is not clear where exactly your NaN values appear. If one of the component rectangles has NaN as a coordinate, it will not be drawn at all - so effectively it is fully transparent. However providing NaN as a color value will not in general produce transparency. As a special case the with image plot style does know to omit pixels with value NaN, but other plot styles don't have a notion of 'pixels'.
I would like get something like this:
Rectangle outside graph:
Could I get that with set object <number> rect ? Or is this only to draw rectangles inside graph?
you can use the screen coordinates (which refer to the entire window) like so:
set object 1 rect from screen 0.0, screen 0.9 to screen 0.1, screen 1.0
this would create a rectangle in the top left 10% of the plotting window
As suggested in #ewcz's answer, you can use screen coordinates for drawing objects (partly) outside the graph area .
However, if you check help object and you will find the option noclip at least since gnuplot 4.6.5. (default is clip).
With this you can draw objects outside the graph using, e.g. graph, first, second, etc. coordinates as well (check help coordinates), especially in case you want to adjust the size of your rectangle to graph or x/y-coordinates.
Script:
### draw rectangle outside graph area
reset session
set xrange [0:20]
set yrange [0:10]
set xlabel "x-axis"
set ylabel "y-axis"
set origin 0.1, 0.1
set size 0.8, 0.8
set obj 1 rect noclip from graph -0.1, 0.9 to graph 0.1, 1.1
set obj 1 fs empty border rgb "red" lw 2 dt 4
set obj 2 rect noclip from first -2,-2 to first 7,3
set obj 2 fs empty border rgb "green" lw 2 dt 1
set obj 3 rect noclip from screen 0.6,0.6 to screen 1,1
set obj 3 fs empty border rgb "blue" lw 2 dt 3
plot x
### end of script
Result: