Trouble with plot matrix with image and xrange - matrix

I have trouble with xrange. When I put 'set autoscale xfix' image is ok but information axis not. When i put xrange [-1:1] i get info ok but images is damage. Second trouble is flip image. In my data stored in file upper left corner is -1 on image is +1, why?
my data is:
-0.999770 -0.998743 0.946455 0.999678 0.999777
-0.699447 -0.999784 -0.999565 -0.076214 0.999467
0.999921 -0.717181 -0.999790 -0.999734 -0.959481
0.999943 0.999920 -0.733798 -0.999793 -0.999786
0.999943 0.999943 0.999920 -0.749453 -0.999794
my code is:
set terminal png transparent enhanced font "arial,10" fontscale 1.0 size 600, 400
set output 'out.png'
set xtics 0.25
set ytics 0.25
set xrange [-1:1]
set yrange [-1:1]
set cbrange [-1:1]
plot 'data.txt' matrix with image
My image is -1 to 1 step 0.5
if I add set xrange [-1:1] and set yrange [-1:1] I get
$ gnuplot -V
gnuplot 5.0 patchlevel 3

the thing is that your data file is interpreted as a uniform matrix. In this case:
gnuplot> help matrix
Gnuplot can interpret matrix data input in two different ways.
The first of these assumes a uniform grid of x and y coordinates and assigns
each value in the input matrix to one element M[i,j] of this uniform grid.
The assigned x coordinates are the integers [0:NCOLS-1].
The assigned y coordinates are the integers [0:NROWS-1].
So this means that the datapoints in the first row of your file will have y-coordinate set to 0, second row 1, etc. However, since the y-axis by default points upwards, the resulting image is therefore flipped. Also, these points define the centers of the elementary color squares/boxes in the plot. So that's way the "effective x/y-range" is in your case [-0.5:4.5].
To "fix" the y-axis, you could use
set yr [] reverse
Here, [] specifies that the axis is still autoscaled.
Finally, to rescale your image from [0,4] into the [-1,1] range, you could use:
fn(x) = x/2. - 1
plot 'data.txt' matrix u (fn($1)):(fn($2)):3 w image
So in total:
set terminal png transparent enhanced font "arial,10" fontscale 1.0 size 600, 400
set output 'out.png'
set xtics 0.25
set ytics 0.25
set xrange [-1:1]
set yrange [-1:1] reverse
set cbrange [-1:1]
fn(x)=x/2-1
plot 'data.txt' matrix u (fn($1)):(fn($2)):3 w image
EDIT:
One could also adapt the script above to deal with a matrix of a priori unknown size:
set terminal png transparent enhanced font "arial,10" fontscale 1.0 size 600, 400
set output 'out.png'
set xrange [-1:1]
set yrange [-1:1] reverse
set cbrange [-1:1]
fName = 'data.txt'
stats fName nooutput
N = STATS_records - 1
set xtics 1./N
set ytics 1./N
fn(x)=(2*x/N)-1
plot fName matrix u (fn($1)):(fn($2)):3 w image
Here, the stats command first scans the file and stores the number of records into a special variable STATS_records. The function fn then rescales the range [0:STATS_records-1] on [-1:1]. Also, the x/y-tics are adapted automatically.

Related

Animation with gnuplot : only one cruve plotted in an animation whereas 2 expected

I have the following script which is expected to produce the animations of 2 curves :
#!/bin/bash
for i in {1..397}; do
gnuplot -p <<-EOFMarker
set terminal png;
set output "pic$i.png";
set title "power spectrum";
set xlabel "scale (k)";
set ylabel "P(k)";
set key top left;
set grid;
set ytics out nomirror;
set xtics out nomirror;
set logscale x;
set logscale y;
set format x "10^{%L}";
set yrange [0:30000];
plot "CAMB-1.3.5/matter_camb$i" u 1:2 w l;
replot "EFTCAMB_v3_beta/matter_eftcamb$i" u 1:2 w l;
EOFMarker
done
# Build movie with ffmpeg
ffmpeg -start_number 1 -i pic%d.png movie.mpeg
Every works fine excepted the fact that only one curve is plotted in animation (CAMB-1.3.5) :
Here is an example of frame :
Why the "replot" command is not taken into account in the generated image ?
Just for the sake of the SO-rule "no answer in comments":
Check help plot:
Syntax:
plot {<ranges>} <plot-element> {, <plot-element>, <plot-element>}
Examples:
plot sin(x)
plot sin(x), cos(x)
plot f(x) = sin(x*a), a = .2, f(x), a = .4, f(x)
plot "datafile.1" with lines, "datafile.2" with points
plot [t=1:10] [-pi:pi*2] tan(t), \
"data.1" using (tan($2)):($3/$4) smooth csplines \
axes x1y2 notitle with lines 5
plot for [datafile in "spinach.dat broccoli.dat"] datafile

Centering labels on a pie chart

I am following this post to make a pie chart using Gnuplot. The only problem with the approach is that I can't align my percentage labels. What am I missing here?
DATA FILE:
"Others" 1.085117e-01 3.904323e-02
"D_o" 2.894902e-01 6.145359e-01
"{/Symbol b}_o" 5.760601e-01 3.760299e-01
"O_h" 5.393108e-01 1.000000e+00
"D_p" 6.743313e-01 2.284404e-01
"{/Symbol a}_p" 1.000000e+00 1.271822e-01
"{/Symbol b}_f" 4.020115e-01 2.233656e-01
"D_m" 2.389996e-01 8.577689e-02
"{/Symbol a}_m" 3.601146e-01 1.033153e-01
"{/Symbol b}_m" 5.596836e-01 1.947165e-01
CODE:
#!/usr/bin/gnuplot
# Terminal & Encoding
set terminal epscairo enhanced color dashed rounded size 8.5, 4.5
set output 'mu_piechart.eps'
set termoption enhanced
set encoding utf8
# Get Status
filename = './datafile.dat'
stats filename u 2 noout
# Get Angles & Percentages
ANG(x)=x*360.0/STATS_sum
PER(x)=x*100.0/STATS_sum
# Square Canvas
set size square
set xrange [-1:1.5]
set yrange [-1.25:1.25]
set style fill solid 1
# Remove Base Properties (Titles, Tics, Axis, Palette)
unset key
unset tics
unset border
unset colorbox
# Initial Angle, Mid Angle, Initial Color
A = 0.0; M = 0.0; i = 0;
# Palette
set palette defined (1 1 0.788 0.055, 2 0.090 0.161 0.659)
# Plot
plot for [i=0:STATS_records-1] filename u (0):(0):(1):(A):(A=A+ANG($2)):(i) every ::i::i with circle linecolor palette,\
filename u (M=A+ANG($2), A=2*M-A, M=M*pi/360.0, -0.5*cos(M)):(-0.5*sin(M)):(PER($2) > 8.00 ? sprintf('%.1f\%', PER($2)) : " ") every ::1 w labels center font ',10',\
for [i=0:STATS_records-1] filename u (1.45):(i*0.25)-1.11:($1) every ::i::i with labels left,\
for [i=0:STATS_records-1] '+' u (1.3):(i*0.25)-1.11:(i) pt 5 ps 4 lc palette
exit
OUTPUT:
The percentages positions are not correct in the figure generated by the script.
Your labels are at wrong positions, because your label plot starts at 1, i.e. you skip the first entry.
Also, what I don't understand is, why you plot the pie parts counterclockwise, and the labels clockwise.
Here is a working version of you script, without some parts which are superfluous for demonstration. Both labels and pie parts are plotted starting at an angle of A = 0 (note the second initialization between the two plots):
reset
# Get Status
filename = './datafile.dat'
stats filename u 2 noout
# Get Angles & Percentages
ANG(x)=x*360.0/STATS_sum
PER(x)=x*100.0/STATS_sum
# Y position of key point and label
YLBL(row) = 2.0 * (row - 0.5*(STATS_records - 1))/(STATS_records - 1)
# Square Canvas
set size square
set xrange [-1:1.5]
set yrange [-1.25:1.25]
set style fill solid 1
# Remove Base Properties (Titles, Tics, Axis, Palette)
unset key
unset tics
unset border
unset colorbox
# Palette
set palette defined (1 1 0.788 0.055, 2 0.090 0.161 0.659)
# Plot
A = 0.0
plot filename u (0):(0):(1):(A):(A=A+ANG($2)):0 with circle linecolor palette,\
A = 0,\
filename u (M=A+ANG($2), A=2*M-A, M=M*pi/360.0, 0.5*cos(M)):(0.5*sin(M)):(PER($2) > 8.0 ? sprintf('%.1f\%', PER($2)) : "" ) w labels center,\
filename u (1.3):(YLBL($0)):1 with labels offset char 3 left ,\
filename u (1.3):(YLBL($0)):0 pt 5 ps 4 lc palette
The script contains some other improvements:
You don't need to iterate over STATS_records
The text and point for the key are plotted at the same position, the label is shifted with the offset parameter by three character units (offset char 3). That makes fine-tuning easier.

z-range threshold for matrix heat map in Gnuplot

Background:
I have a cross-correlation matrix of rows i and columns j with only z values ranging between -1 and 1. I'm able to output a nice heat map using the following script:
unset key
set tic scale 1
set xtics out
set ytics out
set palette defined (-1 "red", 0 "white", 1 "blue")
set cbrange [-1:1]
set cblabel "Correlation Function"
unset cbtics
set size ratio 1
set xrange [0:588]
set yrange [0:588]
set view map
splot 'file.dat' matrix with image
The Problem:
I want to 'screen out' certain z values, such that -0.50 ≤ z ≤ 0.50 are not taken into account for plotting.
Had a think about this some more, and took onboard the advice offered by Christoph. To achieve what I wanted I changed line from:
set palette defined (-1 "red", 0 "white", 1 "blue")
...to:
set palette defined (-1 "red", -0.5, "white", 0.5 "white", 1 "blue")
Worked like a charm.

problematic Moire pattern in image produced with gnuplot pm3d and pdf output

I'm plotting data using the command files discussed here:
gnuplot contour line color: set style line and set linetype not working
I want to provide different output options. PNG works well, as does the wxt terminal, however, these have fixed resolution, e.g. when I "zoom in" on the plot it gets grainier.
If I use pdf or pdfcairo for the terminal, the resulting file has a Moire pattern. The region in the image over which the Moire pattern is observed can be reduced by using increasing amounts of interpolation in the pm3d command. There are lots of points in the data set in the radial direction, but not many angular sets of data, so I need to interpolate more in that "direction". Using no interpolation results in a very grainy pm3d image, so I have been trying 0,20 to 20,20 or even 20,40. Unfortunately even lots of interpolation does not completely get rid of the Moire pattern, makes the file size HUGE (e.g. the PNG file is around 250kB but the pdf file is over 11MB) and as a result it renders very slowly. I've tried viewing these with Adobe Acrobat Reader 10.1.8 and GSview and the result is the same.
I am interested in using the pdf format because it is ubiquitous and can be zoomed in without excessive loss of detail (unlike PNG).
Below are a couple of screen shots that I captured of the pattern in the resulting pdf output at different levels of interpolation. The first image is the png file for reference as it shows no Moire pattern, 250kB file size.
Next, the pdf output without pm3d interpolation, 72kB file size:
Next, the pdf output using set pm3d map interpolate 0,20, file size 1861kB:
Next, the pdf output using set pm3d map interpolate 10,20, file size 5942kB:
Finally, the pdf output using set pm3d map interpolate 20,20, file size 11515kB:
Why are these Moire patterns generated for the pdf outputs? Is there away around this, that would allow me to still have a vector format that can be zoomed in without (much) loss of resolution?
This is not supposed to be a solution, but rather an explanation and a possible, although ugly workaround.
From time to time there are reports to the gnuplot mailinglists about this issue, but it seems to be related to the viewers. It has to do with the way gnuplot creates the surfaces plots. These are drawn as polygons, which are stitched together. The Moiré patterns you are showing come from wrong rendering between two polygons. That depends on the viewer, the viewer settings and the zoom factor.
The easiest example, to show that effect is the following Postscript file:
%!PS-Adobe-2.0
50 50 moveto 50 0 rlineto 0 50 rlineto -50 0 rlineto closepath 0 setgray fill
100 50 moveto 50 0 rlineto 0 50 rlineto -50 0 rlineto closepath 0 setgray fill
Save this file e.g. as moire.ps and view it, or convert it with ps2pdf and view it. With the Acrobat reader 9.5.1 I see the following:
The Acrobat Reader has a setting Preferences -> Page Display -> Enhance thin lines which can prevent this problem, but causes problems on other parts.
On my system (Debian), all viewers show this patterns, mupdf, firefox, ghostscript, pdftocairo, libpoppler` etc.
So, what to do? For myself I use the following workaround. I splot to a png with high resolution, and reread that file later with plot ... with rgbimage. Then you get your heatmap as bitmap, and the rest is vectorial. In most cases this is no problem, because in any way you have some measurement data with limited resolution, which you interpolate.
Based on the question gnuplot contour line color: set style line and set linetype not working, here is how you can implement it:
reset
set lmargin at screen 0.05
set rmargin at screen 0.85
set bmargin at screen 0.1
set tmargin at screen 0.9
set pm3d map interpolate 20,20
unset key
set cntrparam bspline
set cntrparam points 10
set cntrparam levels increment -6,-6,-24
set contour surface
set linetype 1 lc rgb "blue" lw 2
set linetype 2 lc rgb "blue"
set linetype 3 lc rgb "black"
set linetype 4 lc rgb "orange"
set linetype 5 lc rgb "yellow"
set palette rgb 33,13,10 #rainbow (blue-green-yellow-red)
set cbrange [-18:0]
unset border
unset xtics
unset ytics
set angles degree
r = 3.31
set xrange[-r:r]
set yrange[-r:r]
set colorbox user origin 0.9,0.1 size 0.03,0.8
##################### start changes ##############
set autoscale fix
RES_X = 2000
RES_Y = 2000
save('settings.tmp')
set lmargin at screen 0
set rmargin at screen 1
set bmargin at screen 0
set tmargin at screen 1
unset colorbox
set terminal pngcairo size RES_X, RES_Y
set output '3d-polar-inc.png'
splot 'new_test.dat' nocontour
unset output
load('settings.tmp')
# mapping of the coordinates for the png plotting later
X0 = GPVAL_X_MIN
Y0 = GPVAL_Y_MIN
DX = (GPVAL_X_MAX - GPVAL_X_MIN)/real(RES_X)
DY = (GPVAL_Y_MAX - GPVAL_Y_MIN)/real(RES_Y)
C0 = GPVAL_CB_MIN
DC = GPVAL_CB_MAX - GPVAL_CB_MIN
C(x) = (x/255.0) * DC + C0
# now plot the png
#set terminal pdfcairo size 10cm,10cm
#set output '3d-polar.pdf'
set terminal postscript eps color level3 size 10cm,10cm solid
set output '3d-polar-eps.eps'
set multiplot
set cbrange[GPVAL_CB_MIN:GPVAL_CB_MAX]
plot '3d-polar-inc.png' binary filetype=png \
origin=(X0, Y0) dx=DX dy=DY \
using (C($1)):(C($2)):(C($3)) \
with rgbimage, \
NaN with image t '' # hack for getting the colorbox
# plot the contours
unset surface
unset pm3d
splot 'new_test.dat' w l
###################### end changes #################
# now plot the polar grid only
set style line 11 lc rgb 'black' lw 2 lt 0
set grid polar ls 11
set polar
set logscale r 10
set rrange[10:20000]
unset raxis
set rtics format '' scale 0
#set rtics axis scale
set rtics (20,50,100,200,500,1000,2000,5000,10000,20000)
do for [i=-150:180:30] {
dum = r+0.15+0.05*int(abs(i/100))+0.05*int(abs(i/140))-0.05/abs(i+1)
set label i/30+6 at first dum*cos(i), first dum*sin(i) center sprintf('%d', i)
}
set label 20 at first 0, first -(log(20)/log(10)-1) center "20"
set label 100 at first 0, first -(log(100)/log(10)-1) center "100"
set label 200 at first 0, first -(log(200)/log(10)-1) center "200"
set label 1000 at first 0, first -(log(1000)/log(10)-1) center "1k"
set label 2000 at first 0, first -(log(2000)/log(10)-1) center "2k"
set label 10000 at first 0, first -(log(10000)/log(10)-1) center "10k"
set label 20000 at first 0, first -(log(20000)/log(10)-1) center "20k"
plot NaN w l
unset multiplot
unset output
With pdfcairo this gives a 1.7 MB pdf file, with epslatex level3 (this option is available in the 4.7 development version only) you get a 1.5 MB eps file, which can be converted with epstopdf to a 136 KB pdf file.
See also my answer to Big data surface plots: Call gnuplot from tikz to generate bitmap and include automatically? on TeX.SX.

gnuplot add scale and offset to xtics?

I'm plotting a 600px*600px image in gnuplot, and I would like to have the xtics correspond to a different coordinate system than the pixel system. as it is, the xtics go 0, 100, 200, ..., 500, 600. I would like to make them be at the same place, but have different values. Is there a way to make it so that the tics are uniformly modified, like, xtic[i] = (xtic[i]*c1) + c2?
EDIT: Here's my code. Also, I should clarify that what I'm trying to do is have the xtics and ytics correspond to longitude and latitude specifically. So for instance, I would like to add in a transformation such that xtic=0 -> xtic=$minlat, and xtic=$maxx -> xtic=$maxlat.
#!/bin/sh
inputfilename=$1
outputfilename=$2
minlat=$3
maxlat=$4
minlon=$5
maxlon=$6
imagexsize=$7
imageysize=$8
maxx=$(($imagexsize - 1))
maxy=$(($imageysize - 1))
windowxsize=$(($imagexsize+5+5))
windowysize=$(($imageysize+5+5))
imagename=${inputfilename%.*}
gnuplot <<EOF
set terminal png size $windowxsize,$windowysize
unset key
unset colorbox
set output "$outputfilename"
set lmargin 5
set bmargin 5
set rmargin 5
set tmargin 5
set size square
set xrange [0:${maxx}]
set yrange [0:${maxy}]
set palette grey
set label "$imagename" at screen 0.3,0.95
plot "$inputfilename" binary array=${imagexsize}x${imageysize} format='%ushort' with image
EOF
You can accomplish this quite easily by adding a 'using' argument to your 'plot' command.
Here's an example with an added offset of 10 & scale of 0.5:
plot '-' using (($1+10)/2):(($2+10)/2) with linespoints
1 2
3 4
5 6
e

Resources