How to change jqplot series display order/logic - jqplot

Can someone please advise how can I make jqplot charts display series a little bit differently (I am referring to the logic / order not the design).
For example lets say I have something like this:
var series1 = [1, 2, 3];
var series2 = [4, 5, 6];
var series3 = [7, 8, 9];
var ticks = ['JAN','FEB','MAR'];
The standard plotting will place the first value of every series array in 'JAN', the second in 'FEB' and the third in 'MAR'.
I want to display the entire series1 in 'JAN', series2 in 'FEB' and series3 in 'MAR'.
The arrays may not even be of the same size (series2 and series3 may have more or less elements than series1).
Any advice is apreciated,
Thank you!

Related

Reorder columns and rows of Holoviews Heatmap based on similarity measure (e.g. cosine similarity etc.)

I was surprised that no one seems to have asked this before.
Assuming I have a pandas dataframe (random example), I can get a heatmap with Holoviews and Bokeh renderer:
rownames = 'ABCDEFGHIJKLMNO'
df = pd.DataFrame(np.random.randint(0,20,size=(20, len(rownames))), columns=list(rownames))
hv.HeatMap({'x': df.columns, 'y': df.index, 'z': df},
kdims=[('x', 'Col Categories'), ('y', 'Row Categories')],
vdims='z').opts(cmap="viridis", width=520, height=520)
The data (x and y) is categorical, therefore the initial order of rows or columns is unimportant. I wanted to sort rows/columns based on some similarity measure.
One way is to use seaborn clustermap:
heatmap_sns = sns.clustermap(df, metric="cosine", standard_scale=1, method="ward", cmap="viridis")
The output looks like this:
Columns and rows have been ordered according to similarity (in this case, cosine based on dot product; others are available such as 'correlation' etc.).
However, I want to display the clustermap in Holoviews. How do I update ordering of the original dataframe from the seaborn matrix?
A much cleaner approach to Alex's answer (i.e. that was the accepted answer earlier) is to use the data2d property of the returned object from sns.clustermap() function. This property contains the reordered data (i.e. the data after clustering). So:
df_ro = heatmap_sns.data2d
replaces all the following lines:
# get col and row names by ID
colname_list = [df.columns[col_id] for col_id in
heatmap_sns.dendrogram_col.reordered_ind]
rowname_list = [df.index[row_id] for row_id in
heatmap_sns.dendrogram_row.reordered_ind]
# update dataframe
df_ro = df.reindex(rowname_list)
df_ro = df_ro[colname_list]
It is possible to access the indices of reordered columns/rows from the seaborn clustermap using:
> print(f'rows: {heatmap_sns.dendrogram_row.reordered_ind}')
> print(f'columns: {heatmap_sns.dendrogram_col.reordered_ind}')
rows: [5, 0, 13, 2, 18, 7, 4, 16, 12, 19, 14, 15, 10, 3, 8, 6, 17, 11, 1, 9]
columns: [7, 1, 10, 5, 9, 0, 8, 13, 2, 6, 14, 3, 4, 11, 12]
To update row/column order of the original dataframe:
# get col and row names by ID
colname_list = [df.columns[col_id] for col_id in heatmap_sns.dendrogram_col.reordered_ind]
rowname_list = [df.index[row_id] for row_id in heatmap_sns.dendrogram_row.reordered_ind]
# update dataframe
df_ro = df.reindex(rowname_list)
df_ro = df_ro[colname_list]
I've done it here by first getting the names, perhaps there's even a direct way to update columns/rows by indices.
hv.HeatMap({'x': df_ro.columns, 'y': df_ro.index, 'z': df_ro},
kdims=[('x', 'Col Categories'), ('y', 'Row Categories')],
vdims='z').opts(cmap="viridis", width=520, height=520)
Since I have used random data, there's little order in the categories, but still the picture looks a little less noisy. Note that holoviews/df y axis is simply inverse compared to the seaborn clustermap-matrix, that's why the graphic looks flipped.

Is it possible to get non-contiguous slices from an ndarray?

Is it possible to index columns in a Rust ndarray matrix using a Vec rather than a Slice object? The only documentation I can find pertains to slicing using contiguous columns
Specifically, I am trying to implement something like the following code in Python:
x = np.array([[1,2,3,4,5,6], [7,8,9,10,11,12]])
idx = [0,1,2,4]
x[:, idx]
The outcome of x[:, idx] would be the subset of the matrix containing all rows and only columns described in idx, i.e., [0,1,2,4].
I am currently using ndarray (as the title suggests) but I cannot find a way to subset on non-contiguous slices. For instance, you can pass ndarray, which can take a Slice with a start, stop and an index, but I cannot find a way to pass a list of columns that cannot be described using a Slice object.
For instance:
#[macro_use]
extern crate ndarray;
fn main() {
let mut x = array![[1, 2, 3, 4, 5, 6], [7, 8, 9, 10, 11, 12]];
let idx = vec![0, 1, 2, 4];
// The following works as expected
let y = x.slice(s![.., 0..2]);
println!("{:?}", y);
// This is conceptually what I would like to do but
// It does not work.
let y = x.slice(s![.., idx]);
}
The analogue of "advanced indexing" in Numpy is the ArrayBase::select() method:
use ndarray::{array, Axis};
fn main() {
let x = array![[1, 2, 3, 4, 5, 6], [7, 8, 9, 10, 11, 12]];
let idx = vec![0, 1, 2, 4];
println!("{}", x.select(Axis(1), &idx));
}
producing the output
[[1, 2, 3, 5],
[7, 8, 9, 11]]
Note that the resulting array is a copy of the selected elements (just as it is in Numpy). Depending on your use case, you may not need the copy; it's possible you can make do with just iterating over idx and using x.slice(s![.., i]) for all i in idx.

dc.js charts, how to get the intersection of multiple filters

I am wondering if anyone can help me with getting the intersection of multiple filters.
For example:
if I have following:
var ndx = crossfilter([
{id: 1, arrayVals: [1, 2]},
{id: 2, arrayVals: [2, 3]},
{id: 3, arrayVals: [1, 2, 3]}
]);
how do I get items with arrayVals that have 1 and 3? And how do I get the filter value onclick?
As far as I know, within a dc chart the filtering is "OR" and between dc charts, the filtering is "AND".
Thanks Millions,
Anney

How to match a position in an array to a scale in d3

Horrific title, I apologise.
Can someone please help me understand how to achieve the following.
I have a lovely routine that plots a scale, on a map, which is quite customisable in terms of it's orientation, number of colours, etc, the core of which is as follows:
var heatmapColour = d3.scale.linear().domain(d3.range(0, colours.length, 1.0 / (colours.length - 1))).range(colours);
var c = d3.scale.linear().domain(d3.extent(legendDomain)).range([0, 1]);
And if I have an array of colours as the following:
var colours = ["#6363FF", "#6373FF", "#63A3FF", "#63E3FF", "#63FFFB", "#63FFCB", "#63FF9B", "#63FF6B", "#7BFF63", "#BBFF63", "#DBFF63", "#FBFF63", "#FFD363", "#FFB363", "#FF8363", "#FF7363", "#FF6364"];
My routine can generate a legend of Red, Yellow, Green, Cyan and Blue if I set the legendDomain to have 5 entities, or if I set it to 3, would be simply Red, Green, and Blue, etc, etc.
It works perfectly.
However I'm now trying to match some countries to his legend which are based on their order in an array.
So for example, and for simplicity, if I have 50 countries and my legend set to draw 5 colours, I want the first 10 to be Red, the next 10 Yellow, the next 10 Green, etc, etc.
Using the same method to create the legend simply doesn't produce the same results.
Where my legend creates a range of colours within a domain, I now want to kind of go into this backwards and return a colour if 'something' (in this case it's order in the array) falls between the colour values.
Can someone please explain on how to achieve this.
I did something like this:
var colors = ['red', 'green', 'blue', 'brown'];
var countries = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M"];
var heatmapColour = d3.scale.ordinal().range(colors);//i used ordinals instead of linear
countries.forEach(function(d, i){
console.log(d,heatmapColour(Math.floor((i)/colors.length)))
});
working code here
A bit long for a comment, but is this what you are trying to achieve?
// Example arrays
var cols = ['c1', 'c2', 'c3'];
var ctry = [1, 2, 3, 4, 5, 6, 7, 8, 9];
function getCol(cols, i) {
return cols[Math.floor(i / cols.length)];
}
ctry.map(function(d,i) { console.log(getCol(cols, i)); });
(essentially divide index by length of color array and floor).
Fiddle

Different Data Lines on Kendo UI Graphs

I have a Kendo UI line chart.
This has x axis intervals of 28 days and data plotted against this every 28 days.
I want to know if its possible to add a second line but with data plotted daily rather than every 28 days.
Thanks
Yes, you can! This type of series are called scatterLines and basically for each series you have to provide an array of pairs with the x and y values.
If for the first series you provide values 0, 28, 56... and for the second 0, 1, 2... You get what you want.
Example:
$("#chart").kendoChart({
series: [
{ type: "scatterLine", data: [[0, 4], [28, 2], [56, 3]] },
{ type: "scatterLine", data: [[1, 2], [2, 3]] }
]
});
Check it here: http://jsfiddle.net/U7SvD/

Resources