Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Logarithmic chart in FLOT

Tags:

charts

flot

Does anyone have any idea how to create a logarithmic chart in FLOT?

Basically I am trying to create a chart that looks like the one shown here (top left): http://leto.net/plot/examples/logarithms.html

However, I have given it a try using the same options but it doesn't show the chart the same way. I think there must have been a lot of changes to FLOT since then considering that the post is quite old.

If anyone has any idea, please do let me know.

Thanks.

like image 650
developer Avatar asked Nov 16 '11 23:11

developer


3 Answers

You can do this using the "transform" option on the yaxis.

See work here.

$(function () {
    // setup plot
    function sampleFunction(x1, x2, func) {
        var d = [ ];
        var step = (x2-x1)/300;
        for (var i = x1; i < x2; i += step )
            d.push([i, func( i ) ]);

        return d;
    }

    var options1 = {
        lines: { show: true },
        xaxis: { ticks: 4 },
        yaxis: { ticks: [0.001,0.01,0.1,1,10,100],
                 transform: function(v) {return Math.log(v+0.0001); /*move away from zero*/},
                 tickDecimals: 3 },
        grid: { hoverable: true, clickable: true, color: "#999" }
    };

    var data1 = sampleFunction( 0, 5, function(x){ return Math.exp(x)*Math.sin(x)*Math.sin(x) } );

    var plot1 = $.plot($("#chart1"),  [ { label: "exp(x)sin(x)^2", data: data1 } ], options1);
});

Full Working Code:

$(function () {
    // setup plot
    function sampleFunction(x1, x2, func) {
        var d = [ ];
        var step = (x2-x1)/300;
        for (var i = x1; i < x2; i += step )
            d.push([i, func( i ) ]);

        return d;
    }
    
    var options1 = {
        lines: { show: true  },
        xaxis: { ticks: 4 },
        yaxis: { ticks: [0.001,0.01,0.1,1,10,100],
                 transform:  function(v) {return Math.log(v+0.0001); /*move away from zero*/} , tickDecimals: 3 },
        grid: { hoverable: true, clickable: true , color: "#999"}
    };
    
    var data1 = sampleFunction( 0, 5, function(x){ return Math.exp(x)*Math.sin(x)*Math.sin(x) } );
    
    var plot1 = $.plot($("#chart1"),  [ { label: "exp(x)sin(x)^2", data: data1} ], options1);
    
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/flot/0.8.3/jquery.flot.min.js"></script>
<br/><br/>
<div id="chart1" style="width:600px;height:300px;"></div>
like image 104
Mark Avatar answered Oct 20 '22 04:10

Mark


Great work Mark

As the ticks of Y axis in Logarithmic graphs are in the format of power of 10,

I would like to share enhancement in Y axis ticks, Here it is.s

    $(function () {
    // setup plot
    function sampleFunction(x1, x2, func) {
        var d = [ ];
        var step = (x2-x1)/300;
        for (var i = x1; i < x2; i += step )
            d.push([i, func( i ) ]);

        return d;
    }

    var options1 = {
        lines: { show: true  },
        xaxis: { ticks: 4 },
        yaxis: { ticks: [0.001,0.01,0.1,1,10,100],
                 transform:  function(v) {return Math.log(v+0.0001); /*move away from zero*/} , tickDecimals: 3 ,
                 tickFormatter: function (v, axis) {return "10" + (Math.round( Math.log(v)/Math.LN10)).toString().sup();}
                },
        grid: { hoverable: true, clickable: true , color: "#999"}
    };

    var data1 = sampleFunction( 0, 5, function(x){ return Math.exp(x)*Math.sin(x)*Math.sin(x) } );

    var plot1 = $.plot($("#chart1"),  [ { label: "exp(x)sin(x)" + "2".sup(), data: data1} ], options1);
});

Please let me know if there is any better way.

Thanks.

like image 5
Amit Avatar answered Oct 20 '22 04:10

Amit


As the other answerer said, good work Mark. There is a way to make your solution more robust.

Mark's answer will work for most cases, but the plot will not look right for values near or less than 0.0001. Also, you don't need to modify every value to move away from zero. I believe that flot tries to transform 0 to determine where the "bottom" of the plot should be. Because of this, you will not be able to make your plot axis limits dynamic. This will make your plots look very bad if your values are much greater than 0.0001. Therefore, the following modification makes Mark's solution more robust, but it requires knowing the minimum y value (ymin below) in your data.

var options1 = {
    lines: { show: true  },
    xaxis: { ticks: 4 },
    yaxis: { ticks: [0.001,0.01,0.1,1,10,100],
             transform:  Function("v","return v == 0 ? Math.log("+Math.pow(10,ymin)+") : Math.log(v);"), tickDecimals: 3 },
    grid: { hoverable: true, clickable: true , color: "#999"}
};
like image 2
Stephen Hartzell Avatar answered Oct 20 '22 03:10

Stephen Hartzell