Suggestions on interactive time series plotting

Hi all,

I am new to KNIME, and love it so far. I like the R and python integrations, and just found out about the javascript plot integration which looks good but are simple to uase as well. What I am looking for though is a simple to use interactive graph function that allows me to plot time series easily with a combination of line and point data in the same graph. I can already plot a timeseries in a scatterplot, and I can plot a timeseries in a line plot easily with either the builtin plot views or the javascript views (more interactive and prettier to me), but I can't combine the two.

The use-case that I am thinking is that I have monitoring data from a device that gives me events (errors/warnings) and metrics (continuous variables). I want to quickly explore that data by plotting both the events (points) and the continuous variables in a graph and see who the events relate to the continuous variables. I have many different events and many different contious variables, so I would like to be able to interactively choose which events and which continuous variables to display, without having to go back and forth between the node configuration/data flow, and then re-run the view everytime I want to change a variable.

And added bonus would be to be able to interactively zoom in/pan on the timespan to display. I can imagine this would also have performance benefits where only a selection of the points is used to display a long timespan (thus limiting the amount of points to render) and as you zoom in, more detail is added by rendering additional points. It would allow the graph to circumvent the memory/row limitation that is there now in many of the views.

I know this is probably possible using one of the many python plotting tools, or R, but with the plethora of options available and the flexibility of KNIME I have a hard time choosing where to spend effort to get this realised. And for now, the better the integration with KNIME, the better the option would be for me. Speed of data exploration and ease-of-use (after the initial setup) are important to me. 

Cheers,

Dolf.

Nice, I can answer my own question. THe following post sent my on the right track: http://marcoghislanzoni.com/blog/2016/04/29/knime-3-charting-with-plotly-js/

Using the plotly javascript api and a generic javascript node allows me to use plotly for plotting, which is awesome. With a relatively simple script I can make a very pretty plot of my timeseries with both points and lines in there, two different y-axes (one for the point data and one for the continuous variables) and the builtin zoom and pan functionality of plotly is enough for me, but sliders are also possible.

With my 2-300,000 rows it performs amazingly.

The javascript code I ended up with (for inspiration or a starter) is this:

// Load Plotly - Requires jQuery (tick in Dependencies above)
require.config({
    paths: {
        'Plotly': 'https://cdn.plot.ly/plotly-latest.min'
    }
});

// Instantiates Plotly
require(['Plotly'], function(Plotly) {

            // Load values to plot from input data table
            // column 0 is location (i.e. country)
            // column 1 is alcohol consumption at location
            var time = knimeDataTable.getColumn(166);
            var BatSoc = knimeDataTable.getColumn(8);
            var TotBatCur = knimeDataTable.getColumn(17);
            var InvPwrAt = knimeDataTable.getColumn(37);
            var ExtVtg = knimeDataTable.getColumn(55);
            var ExtPwrAt = knimeDataTable.getColumn(77);
            var GdFeedPwrAt = knimeDataTable.getColumn(130);
            var GdCsmpPwrAt = knimeDataTable.getColumn(133);
            var TotPvPwrAt = knimeDataTable.getColumn(136);

            var Derate = knimeDataTable.getColumn(155);
            var ExtVtgLo = knimeDataTable.getColumn(158);
            var ExtVtgLoss = knimeDataTable.getColumn(159);
            var CheckBat = knimeDataTable.getColumn(160);
            var LoBatMod2 = knimeDataTable.getColumn(161);
            var LoBatMod3 = knimeDataTable.getColumn(162);
            

            // Add the DIV for the plot to the DOM
            // id of the DIV is "chart"
            $(document.body).append('<div id="chart"  style="width:1024px; height: 600px;"></div>');

                // ******************************
                // Your Plotly drawing code goes here
                // ******************************

                var data = [
				{
					type: 'scatter',
					mode: 'lines',
					x: time,
					y: BatSoc,
					name: 'BatSoc'
				},
				{
					type: 'scatter',
					mode: 'lines',
					x: time,
					y: TotBatCur,
					name: 'TotBatCur'
				},
				{
					type: 'scatter',
					mode: 'lines',
					x: time,
					y: InvPwrAt,
					name: 'InvPwrAt'
				},
				{
					type: 'scatter',
					mode: 'lines',
					x: time,
					y: ExtVtg,
					name: 'ExtVtg'
				},
				{
					type: 'scatter',
					mode: 'lines',
					x: time,
					y: ExtPwrAt,
					name: 'ExtPwrAt'
				},
				{
					type: 'scatter',
					mode: 'lines',
					x: time,
					y: GdFeedPwrAt,
					name: 'GdFeedPwrAt'
				},
				{
					type: 'scatter',
					mode: 'lines',
					x: time,
					y: GdCsmpPwrAt,
					name: 'GdCsmpPwrAt'
				},
				{
					type: 'scatter',
					mode: 'lines',
					x: time,
					y: TotPvPwrAt,
					name: 'TotPvPwrAt'
				},
		
				{
					type: 'scatter',
					mode: 'markers',
					x: time,
					y: Derate,
					name: 'Evt_Derate',
					marker: { size: 12, symbol: 'diamond'},
					yaxis: 'y2',
				},
				{
					type: 'scatter',
					mode: 'markers',
					x: time,
					y: ExtVtgLo,
					name: 'Evt_ExtVtgLo',
					marker: { size: 12, symbol: 'diamond'},
					yaxis: 'y2',
				},
				{
					type: 'scatter',
					mode: 'markers',
					x: time,
					y: ExtVtgLoss,
					name: 'Evt_ExtVtgLoss',
					marker: { size: 12, symbol: 'diamond'},
					yaxis: 'y2',
				},
				{
					type: 'scatter',
					mode: 'markers',
					x: time,
					y: CheckBat,
					name: 'Evt_CheckBat',
					marker: { size: 12, symbol: 'diamond'},
					yaxis: 'y2',
				},
				{
					type: 'scatter',
					mode: 'markers',
					x: time,
					y: LoBatMod2,
					name: 'Evt_LoBatMod2',
					marker: { size: 12, symbol: 'diamond'},
					yaxis: 'y2',
				},
				{
					type: 'scatter',
					mode: 'markers',
					x: time,
					y: LoBatMod3,
					name: 'Evt_LoBatMod3',
					marker: { size: 12, symbol: 'diamond'},
					yaxis: 'y2',
				}
                ];
                var layout = {
			 	yaxis: {title: 'Variables'},
			  	yaxis2: {
			    		title: 'Events',
			    		titlefont: {color: 'rgb(148, 103, 189)'},
			    		tickfont: {color: 'rgb(148, 103, 189)'},
			    		overlaying: 'y',
			    		side: 'right',
			    		range: [0,1.1],
			  	}  	
                };

                Plotly.newPlot('chart', data, layout);

                // ******************************
                // End of Plotly drawing code
                // ******************************

            });

 

1 Like

Ok, I was absolutely wrong about the performance side of it. My KNIME flow actually only selected a few 100 rows (incorrectly), which caused the awesome performance. Even with 5000 rows the performance of the javascript/plotly graph became bad, and I actually want to plot 100,000 rows over a whole lot of columns. Even the plotly benchmarks on https://plot.ly/benchmarks/ show that that is not an option.

My question therefore continues. I have tried bokeh (from a python node), but am not happy about it (very labour intensive to get some interactive legend working, and performance still not great). So on to other options. I am now thinking maptplotlib using a python node as well.

Hey Dolf,

Since you're obviously not code-averse, the rCharts project should be interesting for your experiments:

http://ramnathv.github.io/rCharts/

It has all the awesome JS charting libraries rolled into one R interface.

HTH,
E

2 Likes