Make D3 multi line chart in X1-Y1-X2-Y2 and X1-Y1-Y2-Y3 format - d3.js

I want to make two types of graph from the data array by using d3. The first graph should be having 2 x-axis values and 2 y-axis values i.e. X1-Y1-X2-Y2, so there will be 2 lines in the chart. In the second type, the data is having 1 x-axis value and other 3 are y-axis values, so the data will be having 3 lines in the chart. The data array example might be like this,
//data for X1-Y1-X2-Y2 format
var data1 = [
{x1:10, y1:43, x2:15, y2:55},
{x1:20, y1:33, x2:22, y2:21},
{x1:30, y1:56, x2:27, y2:29},
]
//data for X1-Y1-Y2-Y3 format
var data2 = [
{x1:10, y1:43, y2:15, y3:55},
{x1:20, y1:33, y2:22, y3:21},
{x1:30, y1:56, y2:27, y3:29},
]

Related

Seaborn grouped Bar plot

I am trying to create visualizations for recent commonwealth medal tally dataset.
I would like to create a grouped bar chart of top ten countries by total number of medals won.
Y axis = total
x axis = Country name
How can I divide totals into three bars consisting of no of :
gold, Silver,Bronze medals won by each country?
I created one using excel, but don't know how to do it using seaborn
P.S. I have already tried using a list of columns for hue.
df_10 = df.head(10)
sns.barplot(data = df_10, x = 'team' , y = 'total' , hue = df_10[["gold" ,
"silver","bronze"]].apply(tuple , axis = 1) )
Here is the chart that I created using excel:
enter image description here
To plot the graph, you will need to change the dataframe to the format that will allow for easy plotting. One of the ways to do this is using dataframe.melt(). The method used by you may not work... Once the data is in a format that seaborn understands easily, plotting will become simple. As you have not provided the format for df_10, I have assumed the data to have 4 columns - Country, Gold, Silver and Bronze. Below is the code...
## Use melt using Country as ID and G, S, B as the rows for values
df_10 = pd.melt(df_10, id_vars=['Country'], value_vars=['Gold', 'Silver', 'Bronze'])
df_10.rename(columns={'value':'Count', 'variable':'Medals'}, inplace=True) ##Rename so the plot has informative texts
fig, ax=plt.subplots(figsize=(12, 7)) ## Set figure size
ax=sns.barplot(data=df_10, x='Country', y='Count', hue='Medals') ## Plot the graph

D3 - Add data points using data in chart

I have a stackblitz here - https://stackblitz.com/edit/d3-one-y-axis?embed=1&file=src/app/bar-chart.ts&hideNavigation=1
I have a stacked bar chart with line chart on top.
The bar chart and line chart have two different data sets and I'm using a seond y-axis to plot the line chart data.
The line chart points are the totals for the two stacked charts in each months column.
Instead of having separate data and y-axis for the line chart is it possible to add up the data from the each months stacked bar and plot that on the graph using one y axis
It can be achieved in several ways. You can either redefine line.x, .y and .defined accessors using all three d, i, data arguments or you can map the data like this:
.data(
linedata.reduce(function(acc, current, index) {
let isFirstPair = index % 2 === 0;
let currentDate = that.y1(current.date)
let currentValue = that.y1(current.value)
if (isFirstPair) {
acc.push({ date: currentDate, value: currentValue });
} else {
acc[acc.length - 1].value += currentValue;
}
return acc;
}, [])
)
It will create a new object for every consequent pair in the source array. You may need to tweak the date or .x accessor.

Changing colors on dimple.js scatter plot

How can I change the color of the circles on a scatter plot based on one of the fields that I'm not using on neither of the axes?
Example, this code:
var myChart3 = new dimple.chart(svg3, data);
myChart3.addMeasureAxis("x", "salary");
myChart3.addMeasureAxis("y", "bonus");
var mySeries = myChart3.addSeries(["Index","a"], dimple.plot.scatter);
myChart3.draw();
produces this graph:
but I also would like to color the bubbles based on a third field called "department"
thanks
The first parameter of addSeries determines colours. In the case of an array the last element is used, so you just need to do:
var mySeries = myChart3.addSeries(["Index","a","department"], dimple.plot.scatter);

Apply Filter from one Crossfilter dataset to another Crossfilter

I have two datasets that have similar columns/dimensions but are grouped differently by row and contain different measures.
Ex:
Dataset 1
Year Category SubCategory Value01 Value02
2000 Cars Sport 10 11
2000 Cars Family 15 16
2000 Boats Sport 20 21
2000 Boats Family 25 26
...
Dataset 2
Year Category ValueA ValueB
2000 Cars 100 101
2000 Boats 200 201
...
Dataset 1 has its own crossfilter object, Dataset 2 has a separate crossfilter object. I have multiple dc.js charts, some tied to the dataset 1, some to dataset 2.
When a dc.js chart filters dataset 1 on a column/dimension that also exists in dataset 2, I want to apply that same filter to dataset 2. How can this be achieved?
I don't think there is any automatic way to do this in crossfilter or dc.js. But if you're willing to roll your own dimension wrapper, you could supply that instead of the original dimension objects and have that forward to all the underlying dimensions.
EDIT: based on #Aravind's fiddle below, here is a "dimension mirror" that works, at least for this simple example:
function mirror_dimension() {
var dims = Array.prototype.slice.call(arguments, 0);
function mirror(fname) {
return function(v) {
dims.forEach(function(dim) {
dim[fname](v);
});
};
}
return {
filter: mirror('filter'),
filterExact: mirror('filterExact'),
filterRange: mirror('filterRange'),
filterFunction: mirror('filterFunction')
};
}
It's a bit messy using this. For each dimension you want to mirror from crossfilter A to crossfilter B, you'll need to create a mirror dimension on crossfilter B, and vice versa:
// Creating the dimensions
subject_DA = CFA.dimension(function(d){ return d.Subject; });
name_DA = CFA.dimension(function(d){ return d.Name; });
// mirror dimensions to receive events from crossfilter B
mirror_subject_DA = CFA.dimension(function(d){ return d.Subject; });
mirror_name_DA = CFA.dimension(function(d){ return d.Name; });
subject_DB = CFB.dimension(function(d){ return d.Subject; });
name_DB = CFB.dimension(function(d){ return d.Name; });
// mirror dimensions to receive events from crossfilter A
mirror_subject_DB = CFB.dimension(function(d){ return d.Subject; });
mirror_name_DB = CFB.dimension(function(d){ return d.Name; });
Now you tie them together when passing them off to the charts:
// subject Chart
subjectAChart
.dimension(mirror_dimension(subject_DA, mirror_subject_DB))
// ...
// subject Chart
subjectBChart
.dimension(mirror_dimension(subject_DB, mirror_subject_DA))
// ...
nameAChart
.dimension(mirror_dimension(name_DA, mirror_name_DB))
// ...
nameBChart
.dimension(mirror_dimension(name_DB, mirror_name_DA))
// ...
Since all the charts are implicitly on the same chart group, the redraw events will automatically get propagated between them when they are filtered. And each filter action on one crossfilter will get applied to the mirror dimension on the other crossfilter.
Maybe not something I'd recommend doing, but as usual, it can be made to work.
Here's the fiddle: https://jsfiddle.net/gordonwoodhull/7dwn4y87/8/
#Gordon's suggestion is a good one.
I usually approach this differently, by combining the 2 tables into a single table (add ValueA and ValueB to each row of Data Set 1) and then using custom groupings to only aggregate ValueA and Value B once for each unique Year/Category combination. Each group would need to keep a map of keys it has seen before and the count for each of those keys, only aggregating the value of ValueA or ValueB if it is a new combination of keys. This does result in complicated grouping logic, but allows you to avoid needing to coordinate between 2 Crossfilter objects.
Personally, I just find complex custom groupings easier to test and maintian than coordination logic, but that's not the case for everyone.

NVD3 X axis incorrect ordering (dates)

I'm trying to visualize 2 series but when I visualize them together, the dates don't go in sequential order anymore.
Here is the fiddle: http://jsfiddle.net/hohenheim/6R7mu/21/ Notice the weird x-axis.
Is there a way to fix the x axis on nvd3?
The data looks like this:
data1 = [{
"date": 1396828800,
"impressions": 49145385
}, {
"date": 1396915200,
"impressions": 46704447
} ....
The NVD3 "multiBarChart" uses an ordinal (category) scale, so it will only display the x-values you give it, in the order in which they are added to the scale. Because your two series only partially overlap on the x axis that's causing problems.
Unlike other NVD3 chart types, the multiBarChart doesn't give you the option of setting your own scale -- it needs to use an ordinal scale in order to generate even widths for the bars. However, you can set the x domain (the list of categories to use for each bar), by calling chart.xDomain(arrayOfXValues).
The array will need to be an ordered array of Date values that spans your data. In order to generate it, you'll need the d3 time intervals range functions. You might also need the d3.extent function to find your max and min values.

Resources