I'm trying to get some eps files from the following lines. The problem is that legend (key) does not pop up when I follow the procedure for making output files. (In my case, \lambda=2 is not shown in ps files.)
Any idea or help will be appreciated.
filename0 = sprintf('/home/hyogeon/ETH/ETH_with_Pf.T/result/data_plot/data_plot_result/Fp_index0_%d_%d,000000_%d,000000_%d_sOkP.tex',9, 5 ,2, 10)
set terminal epslatex size 8, 6 standalone color colortext 10
set output filename0
set xlabel '${\large E}$'
set ylabel '$p$' offset 2
set ylabel rotate by 0
set format '$%g$'
set key at 37, 0.9
filename1 = sprintf('/home/hyogeon/ETH/ETH_with_Pf.T/result/data_refine/p_index0_%d_%f_%f_%d_sOkP',9, 5, 2, 10)
filename2 = sprintf('/home/hyogeon/ETH/ETH_with_Pf.T/result/data_refine/p_index1_%d_%f_%f_%d_sOkP',9, 5, 2, 10)
color1 = '#FF0000'
color2 = '#FF9933'
plot filename1 u 1:2:3 with yerrorbars pt 6 ps 2 lc rgb color1 title '$\lambda = 2$',\
filename2 u 1:2:3 with yerrorbars pt 6 ps 2 lc rgb color2 notitle
I think the problem is that you manually place the key at (37, 0.9), but do not specify the x- and yrange – these are automatically adjusted. Without your data I can't verify, but supposedly your data lies within [-20:20] in x, then your key is placed far outside the graph and therefore not visible.
As a first step you could try deleting the line set key..., see whether the auto placement suits you, and only then fine tune it. Or alternatively, explicitly use set xrange ... and set yrange ...
By the way, you can directly define variables as strings, you don't necessarily need to call sprintf (although you might have reasons to do so):
filename0 = 'home/hyogeon/ETH/ETH_with_Pf.T/result/data_plot/data_plot_result/Fp_index0_9_5,000000_2,000000_10_sOkP.tex'
Related
I use the splot commadn to produce a heat map of the earth. The x- and y-values represent lattitude and longitude of a specific point on the Earth's surface, while the related z-value is the outcome of an analysis. The zrange is between 0 and 60. However, for some locations on Earth, there is no result available (which is correct) and z is set to 9999 for these cases.
I'm using the following script to produce the heat map:
set terminal png large size 1600,\
1200 font arial 24 crop
set output "map.png"
set palette model RGB defined (0 "dark-green",1 "forest-green",2 "green",3 "light-green",4 "dark-yellow",5 "yellow",6 "red",7 "dark-red")
set xrange[-180.00: 180.00]
set yrange[ -90.00: 90.00]
set zrange[ *: 60]
set grid
set pm3d map
set xlabel "Longitude [deg]"
set ylabel "Latitude [deg]"
unset key
set cblabel "Time [h]"
splot "output\\map.dat" u 5:6:8,\
"input\\world.dat" u 1:2:( .00) w l lw 1 lt -1
It works fine but because of the limitation in zrange, regions with z > 60 are shown in white.
I want to have something like a condition which enables that all 9999 z-values are shown in a specific colour like purple with a declaration like "no result" in the legend.
Any idea how to achieve this?
Thanks in advance,
Florian
Not exactly sure how to modify the style for the selected points, but you can use the ternary operator not to draw them at all. Something like:
splot "output\\map.dat" u 5:6:(($8<=60)?($8):(1/0))
You basically want to have 3 "ranges" of colors:
0 to 60 your defined palette colors
>60 "out of range" color
=9999 "no data" color
Not sure if splot ... w pm3d will allow an easy "independent" setting for z and color.
Furthermore, if you have NxN datapoints you will get (N-1)x(N-1) quadrangles and the color is determined by the z-values of the involved vertices (check help corners2color) and http://gnuplot.sourceforge.net/demo_5.5/pm3d.html (the very last graph). Maybe there is an easy way which I am not aware of.
That's why I would perfer the plotting style with boxxyerror (check help boxxyerror), maybe this is not the intended way, but it is rather flexible. If you are running gnuplt 5.4 you have the function palette() (check help palette).
I would take for missing data (backgroundcolor here:white) and for data out of range "grey", but you can easily change it. You can skip the random data generation part and in the plot command replace $Data with your filename and the corresponding columns. As well, replace 180./N and 90./N with the width (delta longitude) and height (delta latitude) of one data element.
Script: (requires gnuplot>=5.4)
### define separate color for missing values
reset session
set xrange[-180:180]
set yrange[-90:90]
# create some "random" test data
N = 90
set samples N
set isosamples N
set table $Data
c = 0.05
x0 = 70 # (rand(0)*360-180) # or random
y0 = -50 # (rand(0)*180-90) #
size0 = 2
x1 = -150 # (rand(0)*360-180) # or random
y1 = -20 # (rand(0)*180-90) #
size1 = 1
holeP0(x,y) = (1-erf((x-x0)*c/size0)**2) * (1-erf((y-y0)*c/size0)**2)
holeP1(x,y) = (1-erf((x-x1)*c/size1)**2) * (1-erf((y-y1)*c/size1)**2)
f(x,y) = rand(0)<holeP0(x,y) || rand(0)<holeP1(x,y) ? 9999 : (sin(1.3*x*c)*cos(.9*y*c)+cos(.8*x*c)*sin(1.9*y*c)+cos(y*.2*x*c**2))*11.5+33
splot f(x,y)
unset table
set palette model RGB defined (0 "dark-green",1 "forest-green",2 "green",3 "light-green",4 "dark-yellow",5 "yellow",6 "red",7 "dark-red")
myZmin = 0
myZmax = 60
myColorNoData = 0xffffff
myColorOutOfRange = 0x999999
set rmargin screen 0.8
set colorbox user origin screen 0.85,graph 0.2 size graph 0.05,graph 0.8
set cblabel "Amplitude"
set cbrange [myZmin:myZmax]
set tics out
set style fill solid 1.0 border
set key noautotitle at graph 1.27, graph 0.15 reverse Left samplen 2
myColor(col) = (z=column(col), z==9999 ? myColorNoData : z>myZmax ? myColorOutOfRange : palette(z))
plot $Data u 1:2:(180./N):(90./N):(myColor(3)) w boxxy lc rgb var, \
"world.dat" u 1:2:(0) w l lc "black", \
NaN w l lc palette, \
keyentry w boxes lc rgb 0x000000 fill empty ti "no data", \
keyentry w boxes lc rgb myColorOutOfRange ti "\ndata out\nof range"
### end of script
Result:
I usually code in Python and do not know any GNUplot but I have to use a small bit of C to plot human cells represented as polygons. I have a file with all the coordinates of the polygon vertices at each time (it is a dynamic simulation), what the code does (and I don't know how) is that it links each cell vertex to form a cell edge and so we can see the different cells. Here is the code used to plot my polygons, the code I was given.
start = 0000
stop = 49990
set terminal pngcairo rounded size 800,800
set style line 1 lt 3 lc rgb pt 7 lw 2
set xrange [0:d*sqrt(N)]
set yrange [0:h*sqrt(N)]
point_files(n) = sprintf('./PointFiles/points%06d.txt', n)
cell_files(n) = sprintf('./CellpopFiles/cells%06d.txt', n)
do for [i = start:stop:10] {
outfile = sprintf('./Figures/figures%06d.png',i)
set output outfile
unset key
plot cell_files(i) w filledcurves ls 1
}
So far the code works but then, I want to separate my cell population in 2 and color the two populations in 2 different colors, that's what I haven't managed. Only one of my cells are colored and even then the cell edges are not shown - I have white (instead of green) and red surfaces moving around but I can't see the limit between each cell, there is no edge.
start = 0000
stop = 49990
set terminal pngcairo rounded size 800,800
set style line 1 lt 3 lc rgb 'red' pt 7 lw 2
set style line 2 lt 3 lc rgb 'green' pt 7 lw 2
set xrange [0:d*sqrt(N)]
set yrange [0:h*sqrt(N)]
point_files(n) = sprintf('./PointFiles/points%06d.txt', n)
cell_files0(n) = sprintf('./Cellpop0Files/cells%06d.txt', n)
cell_files1(n) = sprintf('./Cellpop1Files/cells%06d.txt', n)
do for [i = start:stop:10] {
outfile = sprintf('./Figures/figures%06d.png',i)
set output outfile
unset key
plot cell_files0(i) w filledcurves ls 1
plot cell_files1(i) w filledcurves ls 2
}
Using 'w filledcurves closed ls 1' does not change anything.
The solution might be pretty simple but without knowing any C I've been struggling, thank you in advance!
Plotting multiple files into the same plot can be done by separating the plotting elements via comma. Check help plot.
Syntax:
plot {<ranges>} <plot-element> {, <plot-element>, <plot-element>}
In order to increase the readability of the script and lengthy plot commands, you can introduce "linebreaks" with \ being the very last character in the line (couldn't find the help keyword anymore for this, but I know it is somewhere hidden in help).
Have you tried:
plot cell_files0(i) w filledcurves ls 1, \
cell_files1(i) w filledcurves ls 2
Thanks for the help, in case someone has the same problem as I, here is the code once it works:
N = 100
d = sqrt(2/sqrt(3))
h = sqrt(3)*d/2
start = 0000
stop = 1990
set terminal pngcairo rounded size 800,800
set xrange [0:d*sqrt(N)]
set yrange [0:h*sqrt(N)]
point_files(n) = sprintf('./PointFiles/points%06d.txt', n)
cell_files0(n) = sprintf('./Cellpop0Files/cells%06d.txt', n)
cell_files1(n) = sprintf('./Cellpop1Files/cells%06d.txt', n)
do for [i = start:stop:10] {
outfile = sprintf('./Figures/figures%06d.png',i)
set output outfile
set border
unset key
plot cell_files0(i) with filledcurves fc "royalblue" fs solid 0.5 border lc "black", \
cell_files1(i) with filledcurves fc "yellow" fs solid 0.5 border lc "black"
}
With palette it is easy to create color gradients
set view map
set samp 50,50
set palette defined (0 "blue", 1 "green", 2 "red")
spl "++" us 1:2:1 palette pt 5
Now I would like to apply transparency in vertical direction. The option lc rbg variable supports transparency via the alpha channel (see also here):
spl "++" us 1:2:1:(int(($2+5)/10*255)<<24) lc rgb var pt 5
But how can I translate the palette colors into rgb colors?
A second question: why I get only 10 horizontal rows, albeit I specified 50 in samp?
Easy answer first: When there is 2-dimensional sampling, either automatically from splot or explicitly from plot '++', the number of samples in the first dimension is controlled by set sample and the number of samples in the second dimension is controlled by set isosample.
Now the harder one. In gnuplot versions through the current 5.2.8 you cannot add transparency directly to the palette. You can, however, go through a multi-step process of saving the palette into a file or datablock and then reading it back it as an array of RGB colors. Once you have that array you can add an alpha channel value so that it expresses transparency as well. I will show this process using the datablock created by the command test palette. In older versions of gnuplot you may have to instead use the file created by set print "palette.save"; show palette palette 256;.
# save current palette to a datablock as a list of 256 RGB colors, one per line
set palette defined (0 "blue", 1 "green", 2 "red")
test palette
# print one line to show the format (cbval R G B NTSCval)
print $PALETTE[4]
# Create an array of packed RGB values
array RGB[256]
do for [i=1:256] {
Red = int(255. * word($PALETTE[i],2))
Green = int(255. * word($PALETTE[i],3))
Blue = int(255. * word($PALETTE[i],4))
RGB[i] = Red << 16 | Green << 8 | Blue
}
# Sample from '++' are generated to span ranges on the u and v axes
# I choose 1:256 so that the y coordinates match the range of array indices
set sample 50
set isosample 50
set urange [1:256]
set vrange [1:256]
set xrange [*:*] noextend
set yrange [*:*] noextend
# Now you can use colors stored in the array via colorspec `rgb variable`
# which will also accept an alpha channel in the high bits
plot "++" using 1:2:(RGB[int($2)]) with points pt 5 lc rgb variable
# The final step is to add an alpha channel as a function of y
# Here I go from opaque (Alpha = 0) to 50% transparent (Alpha = 127)
# This works because I know y will run from 1-256
ARGB(y) = RGB[int(y)] + (int(y/2)<<24)
plot "++" using 1:2:(ARGB($2)) with points pt 5 lc rgb variable
Output shown below.
The required command sequence, as you can see, is a mess.
It will be much easier in the next gnuplot release (5.4). The new version will provide a function palette(z) that converts from the current palette directly to a packed RGB value. Note that the palette() function isn't in the -rc1 testing version but will be in -rc2. So in version 5.4 all that palette/array/RGB manipulation can be replaced by
plot '++' using 1:2:(palette($2) + (int($2)<<24)) with points pt 5 lc rgb variable
Check also this: Gnuplot: transparency of data points when using palette
First of all, you can check what your defined palette is doing:
set palette defined (0 "blue", 1 "green", 2 "red")
test palette
You will get this:
Each channel (R,G,B) has a function with an input range [0:1] and an output range [0:1]. In this case it is a linear gradient.
So, you have to define such a function and put the channels together with the transparency (alpha) channel using the bit shift (see help operators binary).
The nice thing about a palette is that gnuplot takes care about the range. Here, you have to know minimum and maximum in advance and scale the color accordingly. You could use stats for this.
Code:
### your own palette with transparency
reset session
r(x) = x < 0.5 ? 0 : 2*x -1
g(x) = x < 0.5 ? 2*x : 2-2*x
b(x) = x < 0.5 ? 1-2*x : 0
a(y) = y
myColor(x,y) = (int(a((y-yMin)/(yMax-yMin))*0xff)<<24) + \
(int(r((x-xMin)/(xMax-xMin))*0xff)<<16) + \
(int(g((x-xMin)/(xMax-xMin))*0xff)<<8) + \
int(b((x-xMin)/(xMax-xMin))*0xff)
set samples 50
set isosamples 50
set size square
xMin=-5; xMax=5
yMin=-5; yMax=5
plot '++' u 1:2::(myColor($1,$2)) w p pt 5 ps 0.5 lc rgb var notitle
### end of code
Result:
I have a text file with 3 columns defining 3D points.
I want to paint every point in 3D and an ellipsoid centered in every point. I discard using the
set parametric
way because I need to iterate my text file.
So i think in doing something like this:
gnuplot
reset
set xrange [-5:5]
set yrange [-5:5]
set zrange [-5:5]
Rx = 1
Ry = 1
Rz = 1
fx(u,v) = column(2) + Rx*cos(u)*cos(v)
fy(u,v) = column(1) + Ry*sin(u)*cos(v)
fz(u,v) = column(3) + Rz*sin(v)
iMax = 200
splot "file.txt" using ($2):($1):($3) title "Input " with points ps 2 pt 7,\
for [i=0:iMax] "file.txt" u (fx(2*pi*i/iMax, pi*i/iMax)):(fy(2*pi*i/iMax, pi*i/iMax)):(fz(2*pi*i/iMax, pi*i/iMax)) notitle with points ps 2 pt 7
But the only think I can get is this strange and heavy (I know that they are a lot of iterations per row, but maybe there is another approach) pattern
Any help? Thank you.
There is something wrong for the mathematic point of view? Using something like this Im perfectly able to plot spheres, but without parsing data:
set parametric
R = 1
set urange [-pi/2:pi/2]
set vrange [0:2*pi]
splot R*cos(u)*cos(v),R*cos(u)*sin(v),R*sin(u) w l lc rgb "yellow"
I assume you want to plot the 2D surfaces of 3D ellipsoids. But the plot command has only a loop over i which is only 1D. This can not give a 2D surface. It might be possible to nest another 1D loop to get this approach to work.
I would suggest something else. Before plotting, you can store the center coordinates into a gnuplot array. Then you loop over this array and plot a sphere/ellipsoid using parametric mode.
This might be a starting point:
# This is the file with the center coordinates.
datafile = "ellipses.dat"
# The "stats" command stores the number of rows in the STATS_records variable.
stats datafile nooutput
num_rows = STATS_records
# Generate arrays which will contain the center coordinates of the ellipsoids.
array centers_x[num_rows]
array centers_y[num_rows]
array centers_z[num_rows]
# Read the center coordinates into the prepared arrays.
# I "misuse" the stats command. The "using" expression in parenthesis executes
# the respective commands and returns the value after the last comma: row + 1.
# This return value is not needed anywhere.
row = 1
stats datafile using (centers_x[row]=$1, \
centers_y[row]=$2, \
centers_z[row]=$3, \
row = row + 1) nooutput
# Output into an image file.
set terminal pngcairo
set output "ellipsoids.png"
# Set parameters for ellipsoids.
Rx = 0.1
Ry = 0.1
Rz = 0.7
# Use parametric mode for plotting.
set parametric
set urange [-pi/2:pi/2]
set vrange [0:2*pi]
# Finally plot:
splot datafile using 1:2:3 title "Input " with points ps 2 pt 7, \
for [i=1:num_rows] centers_x[i] + Rx*cos(u)*cos(v), \
centers_y[i] + Ry*cos(u)*sin(v), \
centers_z[i] + Rz*sin(u) notitle
Please doublecheck x, y, and z: I was not that careful. This is the result:
I have used this example data:
1 2 3
2 2 4
2 3 4
3 3 3
3 4 5
Arrays are available starting with gnuplot 5.2. For older versions, please search the internet for workarounds.
I like to store everything I can in a variable since each gnuplot script I make generates tens of plots at once and it makes things easier to track. Here is a sample of one plot (variable of interest: ytics):
# Setup style
set terminal pngcairo dashed
unset key
set style line 1 pointtype 7 pointsize 0.3 linecolor rgb "black"
# Setup the plots' ytics
ytics_H2 = (0,0.002,0.004,0.006,0.008,0.010,0.012);
# Store the range for each variable
min_T = 200; max_T = 1800;
min_H2 = 0; max_H2 = 0.012;
# Plot
set output 'my_output_H2.png'
set ytics ytics_H2
set xrange [min_T :max_T ]
set yrange [min_H2:max_H2]
plot 'scatter.dat' using 1:2 with points linestyle 1
Here is the result:
As you can see, only the last tick gets printed. If I replace the variable ytics by the vector to which it is set to, everything works as expected.
For such use cases gnuplot has macros:
set macros # necessary only for v < 5.0
ytics = "(1, 5, 8)"
set ytics #ytics
plot x
In order to use macros, you must define a string variable which contains the command parts you want to use at a later point, here ytics = "(1, 5, 8)". Later you can use its content with #ytics.
The important fact here is, that gnuplot first replaces #ytics with the content of the string variable ytics, i.e. expands set ytics #ytics to set ytics (1, 5, 5) and only then executes the whole command.
Because your intervals are fixed and the same, you could also use start, incr, end form:
set ytic 0, 0.002, 0.012