How to fix RGB discrete color range irrespective of data in Gnuplot? - plot

I am trying to make adiscrete color palette using the code as :
set palette defined (0.0 "gray",0.1 "gray", 0.1 "blue", 0.33 "blue", 0.33 "green", 0.67 "green", 0.67 "red", 1.0 "red" )
plot 'Data.dat'u 1:2:3 palette
This is setting a relative color palette taking 0 as minimum value in the data point and 1 as maximum value in data point. That means if my maximum value in data is 0.2, then it is making it red and gray is upto 0.02 (10 percent of maximum).
I want to fix my color range from 0 to 1 irrespective of the data points. That means if the data has maximum value 0.2, it should be blue as it falls in range [0:0.33].
Please help

I think you misunderstand how the palette works in gnuplot. It always runs from 0 to 1, regardless of how you define the color ranges. Plots colored by axis coordinates ("palette z") request a mapping from the axis range into [0:1] on the palette that happens when the data is plotted. That is the default if you simply say "splot DATA with pm3d", but many other coloring strategies are available.
For example, to create a solid color circle at xyz = [1,2,3] that is colored by a palette fraction of 0.6
set object 1 circle at 1,2,3 radius 0.1 \
fillstyle solid fillcolor palette fraction 0.6
This will get you a color that is 0.6 of the way along the palette regardless of what numbers were used to define the palette or the x,y,z values of your data.
The palette displayed on the graph is called the "colorbox" ("cb" for short). You can fix the endpoints of the range it displays by using the command set cbrange [min:max]. If I understand correctly, in your case you want to leave this at [0:1].
I do not fully understand what your data looks like or what you want from it, but let us say you know that the numerical values in column 4 lie between 0.0 and 0.2 and you want that to map onto the full palette range [0:1]. Here is an example.
set palette defined (0 "white", 1 "dark-green")
set cbrange [0:1] # use full palette range even if the data doesn't fill it
set style fill solid
# Columns are x y z color
splot DATA using 1:2:3:4 with pm3d fillcolor palette
Does that help?

Related

How to use GnuPlot to create a plot of droplets of size d versus height and color the droplets by size?

I have a file of x,y,z,d Where x,y,z are the coordinates of a droplet and the diameter of the droplet is d.
I want to do a GnuPlot of the x, z position of the droplet and color it by the diameter from the RGB spectrum scaled from the minimum d to the maximum d.
I have tried using this:
unset hidden3d
set ticslevel 0.5
set view 60,30
set autoscale
set parametric
set style data points
set xlabel "data style point - no dgrid"
set key box
set output 'particles.png'
plot '/directory/kinematicCloud_00000490.dat' \
using 1:3:(0.5-rand(0)):(5.*rand(0)) with points pt 5 ps var lc rgb variable
pause -1
But, the points are being colored here by random colors. I'd like them colored as I said above. So, how do I specify the 3rd and 4th argument to do what I wish?
# Set palette to RGB spectrum (Red = Min; Blue = Max)
set palette model HSV defined (0 0 1 1, 1 0.7 1 1)
# Set min/max of color spectrum to match expected droplet size
set cbrange [0 : MAX]
# 3D plot with points colored by diameter
splot 'data' using 1:2:3:4 with points pointtype 7 lc palette
If you want to discard the y coordinate and make a 2D plot instead, then the command becomes
# 2D plot x/z with points colored by diameter
set view map
splot 'data' using 1:3:(0):4 with points pointtype 7 lc palette

gnuplot: default value for heatmap (if no data is available)

Can you tell me how to specify the default cb (or z) value?
I build a 3d chart {x,y,z} or {x,y,cb}, but for different x there are different ranges of y, and as a result white bars are visible on the chart (for heatmap/colorbox). I would like to see no white stripes, and where there is no data, gnuplot would substitute the default value (for example, 0) and, accordingly, paint the field with the appropriate color for heatmap
You have several options, depending on exactly what plot mode you are using and what type of data you have. In general you can use two properties of the color assignment to get what you want:
1) out-of-bound values are mapped to the color of the extreme min or max of the colorbar. So one option is to assign a palette that has your desired "default" color at the min and max, independent of whatever palette function you use for the rest of the range
2) data values that are "missing" or "not-a-number" generally leave a hole in the grid of a pixel image or heat map that lets the background color show through.
There is a demo imageNaN.dem in the standard demo set that shows use of these features for several 2D and 3D heat map commands. The output from a heatmap generated by splot $matrixdata matrix with image is shown below.You can see extreme values pinned to the min/max of the colorbar range.
Note that if you want some color other than the backgroundn to show through, you could position a colored rectangle behind the heat map surface.
# Define the test data as a named data block
$matrixdata << EOD
0 5 4 3 0
? 2 2 0 1
Junk 1 2 3 5
NaN 0 0 3 0
Inf 3 2 0 3
-Inf 0 1 2 3
EOD
set view map
set datafile missing '?'
unset xtics
set ytics ("0" 0.0, "?" 1.0, "Junk" 2.0, "NaN" 3.0, "Inf" 4.0, "-Inf" 5.0)
set cblabel "Score"
set cbrange [ -2.0 : 7.0 ]
splot $matrixdata matrix using 1:2:(0):3 with image
#Ethan, I really don't have some data, which results in white slits.
I can fill in the missing data 0 at the stage of forming the data file, but then some files become very large and gnuplot spends all the memory.
So I'm looking for a way to solve the problem.
My example:
For #Ethan: my code:
set arrow from 0,86400 rto graph 1, graph 0 nohead ls 5 front
#===> decision of problem
set object rectangle from graph 0, graph 0 to graph 1, graph 1 behind fc rgbcolor 'blue' fs noborder
set pm3d map
# set pm3d interpolate 32,32
set size square
set palette rgbformulae 22,13,-31
splot inputFullPath u 2:1:(percentage($4)) notitle
and my data (for example):
0 1 0.1
0 2 0.2
0 4 0.5
# -------- {0,5..7} - white gap
# -------- {1,1..3} - white gap
1 3 0.6
1 4 0.5
1 7 0.9

Anyone have a way to plot a bean plot in gnuplot?

Title is pretty self explanatory but here is a picture of what I'd like to do. I'm having a tough time figuring out if its even possible.
Plot borrowed from:
Evaluation of geochemical background levels around sulfide mines – A new statistical procedure with beanplots. Gusstavason et al. 2012.
Doing the plot in exactly this orientation could be very cumbersome, if possible at all.
My suggestion is to plot everything with the usual orientation (i.e. having the 'sediments' axis as x-axis, or rather as x2-axis), rotate all labels a bit and finally rotate the complete output by 90 degree (pdf file with e.g. pdftk etc).
With this you can use any plot style as usual. In the script below I just show you how to plot the violet and yellow filled curves (using pseudo data) for two different data sets. Adding the other peaks should be straight forward (plot the bars with e.g. boxes or vector plotting style).
In order to have distinct ytics for the different plots, I associated a certain y-value with a certain plot, 1=Water, ..., 4=Gyttja).
Putting all toghether gives the following script:
reset
set terminal pdfcairo linewidth 2
outfile='bean'
set output outfile.'.pdf'
set encoding utf8
set x2range [0.5:9000]
set logscale x2
set x2tics (1, 5, 10, 50, '' 100, 500, '' 1000, 5000) out
set x2label 'mg/kg (sediments), µg/L (water)'
unset xtics
set yrange[0.5:4.5]
set ytics ('Water' 1, 'Minerogenic' 2, 'Peat' 3, 'Gyttja' 4) center rotate by -90 out
set label at graph 0.95, graph 0.05 right rotate by -90 'Nickel' font ',20' front
# cover possible data overlapping with the label
set object rectangle from graph 0.9, graph 0 to graph 1,graph 0.2 fillcolor rgb 'white' fillstyle solid noborder front
unset key
set macros
fs1="fillcolor rgb '#fc9e00' linewidth 2 fillstyle solid border lt -1"
fs2="fillcolor rgb '#9119f7' linewidth 2 fillstyle solid border lt -1"
# use pseudo data
set samples 500
plot '+' using 1:(4-0.3*exp(-(($1-10)/5.0)**4)) axes x2y1 with filledcurves y1=4 #fs1,\
'' using 1:(4+0.2*exp(-(($1-70)/50.0)**4)) axes x2y1 with filledcurves y1=4 #fs2,\
'' using 1:(1-0.4*exp(-(($1-5)/2.0)**2)) axes x2y1 with filledcurves y1=1 #fs1,\
'' using 1:(1+0.1*exp(-(($1-30)/20.0)**2)) axes x2y1 with filledcurves y1=1 #fs2
set output
system(sprintf('pdftk %s.pdf cat 1W output %s-rot.pdf', outfile, outfile))
system(sprintf('pdftocairo -r 150 -png %s-rot.pdf', outfile))
This gives (conventional and rotated output side-by-side) with 4.6.3:
Some stuff is required for the pseudo data. For a real data file, the plotting line looks a bit differently. The different plots have a separation of 1 in y-direction, so you must scale your data accordingly (done here manually with a scaling factor sc):
sc = 5.1
plot 'datafile.txt' using 1:(4 + $2/sc) axes x2y1 with filledcurves y1=4 #fs1
You can of course also do the scaling automatically, by extracting some minimum/maximum values using the stats command.

Adding transparent circles of defined radius to existing plot in R

I have a data.frame with X and Y coordinate values. X axis is position information and Y axis is log ratio values. The points are colored based log ratio values(green > 0.25 , -0.25 < grey < 0.25, and red < -0.25). The orange dashed horizontal lines are log2 values of 0.58, 0, and -1.
A circular binary segmentation algorithm segments changes in log ratio, indicated by horizontal blue line. In the image attached one can see several segments, most if it close to log2 of 0. Close to the left end of the figure are small blue segment with log value close to 0.58, and a much smaller (almost invisible because of surrounding red points) blue segment at log value close to -1 (right edge of plot). I have x and y coordinates of these blue segments in another data.frame. I want to achieve the following
1) add circles bounding these blue segments above -0.70 < log2 > 0.50. This helps in identifying small segments that could be missed
2) Add transparent colors to these circles using alpha values so that the blue segment is seen
3) The size of the circle would be based on the width of these blue segments.
I am also open to other ideas of highligting these blue segments at -0.70 < log2 > 0.5. Maybe I should suppress plotting the points (green and red) where these blue segments are found. I am using R to make this plot. Appreciate the help.
This was the code used: There are two df objects. The df(X) contains Chr.no, Chr.Start, Chr.End and Log2. The df(Y) is similar, but different col.names such as loc. start, and loc. end. And instead of Log2, they have seg.mean values
for (i in 1:25) { # Plot each chromosome separately
plot(X[which(X$Chr.No ==i),"Chr.Start"], X[which(X$Chr.No ==i),"Log2"], ylim=c(-4.0,4.0), col=X[which(X$Chr.No ==i),"Color"], pch=16, cex=0.4, ylab="Log2", xlab="Genomic Position", main= paste("KCL:180522_SS", "chromosome", i, sep=" "))
abline(h=c(-1,0,log2(3/2)), lty=2, col="chocolate")
xleft = Y[which(Y$Chr.No ==i),"loc.start"] # Left limit of the blue horizontal line
xright = Y[which(Y$Chr.No ==i),"loc.end"] # Right limit of the blue horizontal line
ybottom= Y[which(Y$Chr.No ==i),"seg.mean"] - 0.010 # Adding thickness to the "seg.mean"
ytop = Y[which(Y$Chr.No ==i),"seg.mean"] + 0.010 # Adding thickness to the "seg.mean"
rect(xleft=xleft, ybottom=ybottom, xright=xright, ytop=ytop, col="blue", border="blue")
}
#Dwin Yes, "Color" is a vector of "lightgreen", "grey" and "red". These are the color information for the pch=16 in the plot(x,y). I do not want to modify the pch=16 points. The horizontal "blue" line segments are added by the 'rect', and they span many pch=16 points. As you can see there are many "blue" segments, some very small and some large in length that differ in their log2 values.This is what I want to bound with a filled transparent circle. Not all "blue" segments, but only the ones where the "blue" segment 0.25< log2 > 0.25. In this figure the smaller "blue" segments are close to the edges of the plot, and since they are difficult to spot, I want to highlight them with a filled circle around them. Please let me know if I am still not clear. Thanks
(Deleted incorrect method based on guess about the manner in which the blue points (which were really segments) were being constructed.)
Edit: With the new information I would suggest drawing ordinary "points", i.e, open circles at the x-vector formed by (xleft+xright)/2 and the y-vector using ytop (which should be the same as ybottom) each for the selected ytop values that meet your criteria. You would make a logical vectors to select each of these vectors. So:
selvec <- ytop < -0.70 | ytop > 0.5
points ( x= (xleft[selvec]+xright[selvec])/2, y= ytop[selvec], cex =1.5, col="blue")
You could also use transparency if you used the rgb() function to create a color with transparency:
points ( x= (xleft[selvec]+xright[selvec])/2, y= ytop[selvec], cex = 2, col=rgb(0, 0, 1, 0.3) )
.... should give you transparent circles if your output device supports it.

gnuplot heat map color range

I have some X Y Z data in a file and I'm using gnuplot to display it.
I am creating a heat map, ie. a 2D plot where the Z value is presented using color.
Right now I'm using the following script:
set palette defined (0 "blue", 1 "red")
plot "xyz.dat" u $1:$2:$3 w image
My problem is, gnuplot ignores the 0 and 1 in the palette definition. It uses the colors specified, but rescales according to the minimal and maximal Z value in the file.
This makes it hard to visually compare different plots whose z range is different.
How do I tell gnuplot to stop rescaling the z color range?
The "set palette defined" command maps the grey values that you would get if you were plotting using greyscale onto a color palette; the scaling to min -> 0 and max -> 1 is how it's supposed to work. If you want to make a set of plots all with the same scaling of the data, you want to use the "set cbrange" command. For example,
set cbrange [0:0.5]
set palette defined (0 "blue", 1 "red")
splot '++' using 1:2:(sin($1)*cos($2)) w image
gives you an image plot with the maximum data value of 0.5 mapped to red and 0 mapped to blue.
Subsequent plots, like
splot '++' using 1:2:(0.5*sin($1)*cos($2)) w image
will use the same scaling, so they can be compared.

Resources