Version: (using KDE KDE 3.5.0KDE 3.4.3) Installed from: SuSE RPMsMac OS X (Fink) Packages When a plot is shown in log on the Y axis (I did not test X axis) with a rather small range (from 10 to 300 for instance) the ticks are no longer log-spaced but linearly-spaced. How to reproduce: - Plot a curve in log-log - reduce the size of the Y range using 'Expression' in Edit Plot -> Range - At some point the Y axis goes from log-spaced to linearly-spaced tickmarks Expected Behaviour - Always have log-spaced tickmarks if in log mode
Created attachment 14587 [details] image showing ylog problem
Currently, if max/min<32, the ticks end up in linear tick mode. If it isn't too invasive, could instead happen if Max/Min < 10. If Max/Min<10, there is no promise that there will even be 1 major tick, and so the current behavior should be preserved.
My preference would be to increase it to Max/Min = 100. At present you sometimes get a single labelled tick, which marks it hard to determine what the values of the other ticks are. With Max/Min = 100 you would be assured of two labelled ticks. Another approach would be to use the normal log labels for Max/Min > 100, switch to linear labels for Max/Min < 10, and then label some or all of the minor ticks (in a smaller font?) for 10 <= Max/Min <= 100.
SVN commit 514321 by arwalker: CCBUG:121534 Make existing code clearer in its intent M +9 -5 kst2dplot.cpp --- trunk/extragear/graphics/kst/src/libkstapp/kst2dplot.cpp #514320:514321 @@ -2937,15 +2937,19 @@ auto_tick = _autoTickYLast; } else if (is_log) { if (max - min <= (double)majorDensity && max - min > 1.5) { + // show in logarithmic mode with major ticks nicely labelled and 9 minor ticks + // between each major label... auto_tick = 9; tick = 1.0; } else if (max - min >= (double)majorDensity) { + // show in logarithmic mode with major ticks nicely labelled and no minor ticks... auto_tick = 0; tick = floor((max - min) / (double)majorDensity); if (tick == 1.0) { auto_tick = 9; } } else { + // show in "linear" mode with major ticks linearly spaced and no minor ticks... auto_tick = 0; Exp = pow(10.0, floor(log10(St))); @@ -2960,16 +2964,16 @@ // determine tick interval... Exp = 0; if (base == 60) { - if ((b60_ticks[0]*0.7<St) && - (b60_ticks[n_b60_ticks-1]>St*0.7)) { + if ((b60_ticks[0]*0.7 < St) && + (b60_ticks[n_b60_ticks-1] > St*0.7)) { Exp = 1.0; ticks = b60_ticks; autominor = b60_autominor; nt = n_b60_ticks; } } else if (base == 24) { - if ((b24_ticks[0]*0.7<St) && - (b24_ticks[n_b24_ticks-1]>St*0.7)) { + if ((b24_ticks[0]*0.7 < St) && + (b24_ticks[n_b24_ticks-1] > St*0.7)) { Exp = 1.0; ticks = b24_ticks; autominor = b24_autominor; @@ -2977,7 +2981,7 @@ } } - if (Exp<0.5) { + if (Exp < 0.5) { Exp = pow(10.0, floor(log10(St))); }
The correct solution here is to go to log_2 when there is not enough dynamic range for log_10. I guess it is ok to never go to pseudo-linear. If the user chooses log mode, and there are no tick labels... so be it.
SVN commit 541168 by arwalker: CCBUG:121534 Allow any base for the log scale. This is not currently enabled as further testing is needed. Fix compilation. M +27 -4 libkst/kstmath.h M +125 -110 libkstapp/kst2dplot.cpp M +18 -11 libkstapp/kst2dplot.h M +1 -0 libkstmath/kstbasecurve.cpp M +4 -4 libkstmath/kstbasecurve.h M +28 -26 libkstmath/kstimage.cpp M +55 -53 libkstmath/kstvcurve.cpp
SVN commit 551195 by arwalker: BUG:121534 Go to base 2 when base 10 does not display enough valuse on the axis. M +35 -8 kst2dplot.cpp --- trunk/extragear/graphics/kst/src/libkstapp/kst2dplot.cpp #551194:551195 @@ -756,6 +756,15 @@ if (checkLRange(xmin_in, xmax_in, _xLog, _xLogBase)) { if (_xLog) { + if (_xLogBase == 10.0 && xmax_in - xmin_in < 1.5) { + _xLogBase = 2.0; + xmin_in *= 1.0/log10(2.0); + xmax_in *= 1.0/log10(2.0); + } else if (_xLogBase == 2.0 && xmax_in - xmin_in > 4.0) { + _xLogBase = 10.0; + xmin_in *= log10(2.0); + xmax_in *= log10(2.0); + } XMax = pow(_xLogBase, xmax_in); XMin = pow(_xLogBase, xmin_in); } else { @@ -774,6 +783,11 @@ if (checkLRange(ymin_in, ymax_in, _yLog, _yLogBase)) { if (_yLog) { + if (_yLogBase == 10.0 && ymax_in - ymin_in < 1.1) { + _yLogBase = 2.0; + } else if (_yLogBase == 2.0 && ymax_in - ymin_in > 3.5) { + _yLogBase = 10.0; + } YMax = pow(_yLogBase, ymax_in); YMin = pow(_yLogBase, ymin_in); } else { @@ -1433,7 +1447,7 @@ int accuracy = 0; // check how many decimal places we need based on the scale - getLScale(xmin,ymin,xmax,ymax); + getLScale(xmin, ymin, xmax, ymax); if (isXLog()) { xdelta = (pow(_xLogBase, xmax) - pow(_xLogBase, xmin))/double(pr.width()); } else { @@ -3024,17 +3038,30 @@ tick = _tickYLast; auto_tick = _autoTickYLast; } else if (is_log) { - if (max - min <= (double)majorDensity && max - min > 1.5) { - // show in logarithmic mode with major ticks nicely labelled and 9 minor ticks - // between each major label... - auto_tick = 9; + if (max - min <= (double)majorDensity && ((_xLogBase == 10.0 && max - min > 1.5) || + (_xLogBase == 2.0 && max - min > 1.0))) { + // show in logarithmic mode with major ticks nicely labelled and the specified + // number of minor ticks between each major label... + if (logBase == 2.0) { + auto_tick = 10; + } else if (logBase == 10.0) { + auto_tick = 9; + } else { + auto_tick = 5; + } tick = 1.0; } else if (max - min >= (double)majorDensity) { // show in logarithmic mode with major ticks nicely labelled and no minor ticks... auto_tick = 0; tick = floor((max - min) / (double)majorDensity); if (tick == 1.0) { - auto_tick = 9; + if (logBase == 2.0) { + auto_tick = 10; + } else if (logBase == 10.0) { + auto_tick = 9; + } else { + auto_tick = 5; + } } } else { // show in "linear" mode with major ticks linearly spaced and no minor ticks... @@ -3047,10 +3074,10 @@ tick = ticks[i] * Exp; } } - } + } } else { // determine tick interval... - Exp = 0; + Exp = 0.0; if (base == 60) { if ((b60_ticks[0]*0.7 < St) && (b60_ticks[n_b60_ticks-1] > St*0.7)) {