Notinlist
Notinlist

Reputation: 16650

Logarithmic y with zero in GnuPlot

My goal is to display 0 values on a logarithmic scale a little bit under 1.

I managed to plot my own simple histogram (with boxes) with logarithmic Y scale. My Y values are non-negative integers up to 25000. I cannot differentiate the 0 and 1 values as the Y scale begins at 1. Which is mathematically correct, but I want to hack a zero just under the one.

If I were to write a program that plots my graph, I would add 1 to all of my data, and remove 1 from the Y labels. Is there any tricks that would do something like that for me?

Upvotes: 5

Views: 8781

Answers (3)

Bruce Chetta
Bruce Chetta

Reputation: 11

I hope this can help you. this is not just a "hack", but a real way to have a linear-log y axis on gnuplot:

reset
set terminal wxt 0 enhanced font 'Sans,13'  

#%%%  SIZE SETTINGS (whole figure)
tm = 0.90; bm = 0.2   
lm = 0.12; rm = 0.885
size = 0.8

#%%%  RANGE SETTINGS
y1 = 0.; y2 = 1.;       #(lin interval)
y3 = 1.; y4 = 1000.;   #(log interval)

x1 = -8.0; x2 = 8.0
set xrange [x1:x2]; 

#%%%  SIZE SETTINGS (single plots)
I_1 = abs(y2-y1)
I_2 = abs(log10(y4)-log10(y3))
denom = I_1 + I_2

T_m_1 = lm + size * (I_1/denom)
T_m_2 = lm + size * ((I_1+I_2))/denom)


f(x) = (15.*sin(x)/x)**2


#%%%  BEGIN MULTIPLOT
set multiplot

# Left and Right margins
set lmargin at screen lm
set rmargin at screen rm

# X-axis settings:  
set xlabel "X [ux]"; set format x "%2.1f";
set xtics 2 nomirror; set mxtics 4
do for [i=(x1+1):(x2-1):2]  { 
  set xtics add ("" i)      }

set samples 10000;

# Y-axis label
set label 'Y [uy]'  \
at screen 0.03,bm + 0.5*size \
offset 0,-strlen("X [ux]")/4.0 \
rotate by 90

#%% First plot, first interval
set border 1+2+8
set bmargin at screen bm
set tmargin at screen T_m_1

set yrange [y1:y2]

set format y "%1.0f"; 
set ytics 1; set mytics 5;


plot f(x) lw 2 \
lc rgb "navy" notitle
#%% End first plot

unset xlabel; unset xtics     

#%% Second (and last) plot
set border 2+4+8
set bmargin at screen T_m_1
set tmargin at screen T_m_2

# showing mirror xtics via a x2 axis
set link x via x inverse x
set format x2 ""; 
set x2tics nomirror; set mx2tics 4;
do for [i=(x1+1):(x2-1):2]  { 
 set x2tics add ("" i)      }

set logscale y;
set ytics autofreq; set mytics autofreq; 
set format y "10^{%L}";  
set ytics add ("" 1.0);

set yrange [y3:y4]

plot f(x) lw 2 \
lc rgb "navy" notitle
#%% End second plot

unset multiplot
#%%%  END MULTIPLOT

Result: image

Practical guide to the code:

  • start by modifying the "RANGE SETTINGS" to adapt them to your plot
  • then choose the "X-axis settings" and "Y-axis label" you prefer
  • comment the two lines specifying the ytics and yformat in the "first plot" part (aka let Gnuplot set those for you, for now)
  • modify "first" plot command to plot (between y1 and y2) your function/datafile
  • adapt the part under "showing mirror xtics via a x2 axis" to your X axis setting (if you want specular tics)
  • modify "second" plot command to plot (between y3 and y4) your function/datafile

  • see the result and fix minor details, like labels, formats, tics, mtics, and so on.

Upvotes: 1

Miguel
Miguel

Reputation: 7627

I think the best option would be to plot your histogram using a modified function:

plot 'data' using 1:($2 < 1 ? $2 : log10($2)+1) with boxes

The above command plots the log10()+1 of your data if it is above or equal to 1, otherwise it plots simply your data. Then, you can modify your y axis so that it's linear between 0 and 1 and logarithmic between 1 and the highest value:

ymax = 10000
set yrange [0:log10(ymax)]
unset ytics
set ytics 1 add ("0" 0, "1" 1)
set for [i=2:log10(ymax)] ytics add (sprintf("%g",10**(i-1)) i) # Add major tics
set for [i=1:log10(ymax)] for [j=2:9] ytics add ("" log10(10**i*j) 1) # Add minor tics
set for [j=1:9] ytics add ("" j/10. 1) # Add minor tics between 0 and 1
plot 'data' using 1:($2 < 1 ? $2 : log10($2)+1) with boxes

The 1 after the tic position is to adjust the minor tics' length (thanks to @Christoph). Anyway, this looks like the following figure for a test case x^2, where you can see how the y axis is linear up to 1 and logarithmic beyond:

enter image description here

Upvotes: 4

gboffi
gboffi

Reputation: 25093

gnuplot> set xrange [0:2]
gnuplot> set log y
gnuplot> set yrange [0.1:100]
gnuplot> set ytics ("0" 0.1, "1" 1, "10" 10)
gnuplot> plot cosh(x)
gnuplot> 

Upvotes: 6

Related Questions