Reputation: 16650
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
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:
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
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:
Upvotes: 4
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