"Pretty Print" logarithmic graph lines

54 views
Skip to first unread message

Joel Richards

unread,
Apr 14, 2016, 10:18:46 AM4/14/16
to Flot graphs
Hi all,
I've been developing an embedded web server that uses Flot to plot graphs. When the graph is viewed linearly, Flot's built-in algorithms for ticks / tickIntervals works beautifully!

However, when the graph is in logarithmic mode (base 10 for the purposes of this post), the built-in algorithm for ticks / tickIntervals doesn't work very well. It tends to look at the span without relation to the "logarithmic" span. For example, in the case that there's no data, here's a picture of the plot (note the legend is removed because this is a product in development):



You can see in the picture that the ymin is 0.1, the ymax is 1000000. Flot's tick calculating algorithm graphed 10 ticks between 0.1 and 1000000 and came up with some linearly even-spaced tickIntervals. Of course, the better thing to do here would be to show powers of 10-- 0.1, 1, 10, 100, 1000, 10000, 100000, and 1000000.

However, my product is supposed to feature an autoscale option, where the ymin and ymax would change with the data presented. Here's an example of a log plot with some data:


You can see here the ticks are better calculate because the ymin/max are more closely spaced in terms of spans.

Here's what I am hoping to accomplish:
1. I'd like to see about 10 ticks maximum that are only integer equivalents of powers of 10;
2. I'd like to see about 100 y-axis grid lines for integer equivalents of powers of 10;

RE 1.): Since the ymin and max will vary depending on the data, I'm looking for an algorithm that determines which power of 10 to use, based on the ymax - ymin (y span, if you will).

RE 2.): Since the y-span will encompass varying powers of 10, then the power of 10 to use to determine the grid lines will vary depending on the powers of 10 in the grid line.

For the first graph I showed, the appropriate grid line algorithm is something along these lines:

      // go from the minimum power to the maximum
      for(i = iMinLogPow; i <= iMaxLogPow; i++)
      {
         for(unsigned int j = 1; j < 10; j++)
         {
            // calculate the value for the grid line
            dYLineVal = pow(10, i) + j * pow(10, i);
            
            // see if it's worth marking
            if(dYLineVal > dYMin && dYLineVal < dYMax)
            {
               // we're adding an element
               bDidAddElement = true;
               
               // add in markings element
               pszTracker += sprintf(  pszTracker,
                                       "{ \"yaxis\": { \"from\": %f, \"to\": %f }, \"color\": \"#DDDDDD\" }, ",
                                       dYLineVal, dYLineVal);
               
            }
            // break when we get over the y max
            if(dYLineVal >= dYMax)
            {
               break;
            }
         }
      }

Of course, for the second graph, using that algorithm, there would only show 2 integers of the current power of 10-- 1000 and 2000. Clearly this is too few grid lines (since I'm looking for <100). In the second graph, the algorithm should plot grid lines for 1000, 1100, 1200, etc... until 2000 (the ymax is about 2060 or so).

Basically, I'd like to "beautify" the grid lines to be more intuitive for the end user to look at the graph and logically see the right grid structure. Has anyone ever done anything along these lines, or does anyone have any ideas how to make the graph look more like I want it?

Also-- logarithmic plotting seems common enough that this kind of functionality could be developed into a plugin. I would be more than willing to help out with a plugin if anyone would like to collaborate on figuring out a better log tick algorithm.

Thanks!

Joel
Reply all
Reply to author
Forward
0 new messages