How can I align linear and ordinal scales in d3 graphs? - d3.js

I have an ordinal scale, that I am creating a bar chart with.
I create it like this:
d3.scale.ordinal()
.rangeRoundBands(js.Tuple2(0, widthOfMySvgElem), 0.1)
.domain(labels)
The labels are in fact weeks, or months, or similiar periods, and I have data for those periods.
Now, I have something like expected values, that I want to show in this graph as well.
Furthermore, those expected values can change in time, and I want to display that too.
I want to display, that I have expectedValue1 in march, and the start of April, but then at 7th of April, the expected value changed to expectedValue2, and I want to place it where the 7th of April would be on my axis. (I want to display those expected values as the straight line, that changes height as value change.)
But I have no luck matching exact location in relation to this ordinal axis.
Do you have any ideas how can I successfully align those two scales, so they will meet at the data points of ordinal scale, but that I would be able to position other values correctly as well?

Related

Dimple JS - Removing gap between the y-axis and the chart

I am using dimple.v2.3.0 to create line and area chart. When creating chart with category x-axis, Dimple leaves a gap between the y-axis and the line/area. I would like to ask is there any way to remove the gap?
I'm afraid there isn't a good answer for this, it's done this way because dimple allows you to combine with bars etc. There is a time axis for dates which will not include the gap and therefore answers the majority of cases with area charts, however categorical axes will always have the gap.
There is a hacky workaround you can use in this case where you have integers on your x axis which is to treat them as dates and put them on a time axis:
var x = myChart.addTimeAxis("x", "Call", "%Y", "%-Y");
x.timePeriod = d3.timeYear;
x.timeInterval = 1;
This will parse and display your calls as years and display them on the time axis. The "%-Y" display format shows a 4 digit year with no leading zeroes. This will work for integers up to 9999. Here it is working in your fiddle:
https://jsfiddle.net/zuuaar1t/

dc.js not respecting xUnits

I'm trying to reduce the number of points in a DC.js line chart to improve performance. The docs lead me to believe xUnits() is the way to do this:
The coordinate grid chart uses the xUnits function to calculate the number of data projections on x axis such as the number of bars for a bar chart or the number of dots for a line chart.
but xUnits does not even seem to be used:
http://jsfiddle.net/m5tguakf/2/
What am I doing wrong?
The number of points is actually determined by crossfilter - dc.js doesn't do any aggregation on its own, so it has no way to add or reduce the number of points.
That documentation may be misleading - it doesn't alter the shape of the data. xUnits is really just needed for dc.js to know the number of elements it is going to draw. It's used for two purposes:
to determine the width of bars or box-plots
to know whether the x scale is ordinal or quantitative
Could dc.js just count the number of points in the crossfilter group? Perhaps.
Anyway, to get back to your original question: if you want to reduce the number of points drawn, aggregate your data differently in your group. Usually this means creating larger bins which either sum or average the data which fall into that interval.
As a simple example, you can combine every other point in your fiddle by binning by even numbers, like so:
var BINSIZE = 2;
// ...
speedSumGroup = runDimension
.group(function(r) { return Math.floor(r/BINSIZE) * BINSIZE; })
// ...
http://jsfiddle.net/gordonwoodhull/djrhodkj/2/
This causes e.g. both Run 6 and Run 7 to fall in the same bin, because they have the same group key. In a real example, you'd probably want to average them, as shown in the annotated stock example.

How can I plot data of multiple days on same plot

I have some data which is collected for 6 days during 8:00AM to 11:00AM. I need to plot all the data on same plot one over other. The way I am doing now:
hold on
plot(y1,x1,':b*','MarkerEdgeColor','k')
plot(y2,x2,':r*','MarkerEdgeColor','k')
plot(y3,x3,':y*','MarkerEdgeColor','k')
plot(y4,x4,':g*','MarkerEdgeColor','k')
plot(y5,x5,':c*','MarkerEdgeColor','k')
plot(y6,x6,':w*','MarkerEdgeColor','k')
datetick('x','HH:MM:SS')
hold off
where x1 to x6 has y axis data and y1 to y6 have
y(i) = datenum(Year(1:5), Month(1:5), Input_Vector(1:5,2), Input_Vector(1:5,3), Input_Vector(1:5,4), Input_Vector(1:5,5));
When I plot using above, I get the image attached
But what I need to find patterns by observing them. So I need to have something one above other with x axis 8:00:00 to 11:00:00
I need something like and I got this by making DAY parameter constant date.
If you want to plot one day over another, then the method you used to make the second graph - discarding/replacing the date part of your datetime - is likely the best way to do it. It matches up nicely with the conceptual question that the graph answers, i.e.: "Is there a link between time of day and duration of journey, regardless of the day it was taken on?"
If you still want to preserve the day information, you could always perform the multiple plots with different line specs, and have the legend show which line corresponds to which day.
If the above question - finding a link between time and journey duration - is what you are trying to do, rather than plotting that specific type of graph, I would also try something like this:
Split your day into half hour or quarter hour slots and take the average of all data points in each block. This gives you a single value for each half/quarter hour span.
Plot this as a bar chart with error bars showing standard error (this can be done using bar and errorbars)
If I see anything, try fitting it with an appropriate model and check for goodness of fit. In your case this would probably be a Gaussian model, as your data kinda looks like it peaks around 9:20.

d3.js - Irregular layout on column chart when columns represent months

Check out this quick and dirty example that I threw together: http://zoopoetics.com/d3/irregular_layout.html
d3 is doing its job admirably, laying out the columns at irregular intervals because months are of irregular durations. As we all know, a month can last from 28 to 31 days.
Thing is, the irregular layout is unsettling to the eye. I want the columns to lay out at regular pixel intervals along the horizontal axis.
Looked all over the googles for an answer and found very little about this problem, which suggests that I may be missing something obvious.
Has anyone else been here and surmounted the problem? Thanks!
My first approach would be to use the time x axis but render the bars against a different scale of lets say 365/12 intervals.
The x scale I think should have the month name labels in the middle of each month as well as a tick at the middle:
Here is my version of your file
here

Mac Excel 2011 - Histogram with normal distribution

Let's say I have a list of values and I have already chunked them into groups to make a histogram.
Since Excel doesn't have histograms, I made a bar plot using the groups I developed. Specifically, I have the frequencies 2 6 12 10 2 and it produces the bar plot you see below.
Next, I want to add a normal distribution (line plot) with a mean of 0.136 and standard deviation of 0.497 on top of this histogram. How can I do this in excel? I need the axis to line up such that it takes up the width of the bar plot. Otherwise, you get something like I've attached.
But...the normal should be overlayed on the bar plot. How can I get this effect?
There are two main part to this answer:
First, I reverse-engineered the grouped data to come up with an appropriate mean and standard deviation on this scale.
Second, I employed some chart trickery to make the normal distribution curve look right when superimposed on the column chart. I used Excel 2007 for this; hopefully you have the same options available in your version.
Part 1: Reverse-Engineer
The column B formulae are:
Last Point =MAX(A2:A6)
Mean =SUMPRODUCT(B2:B6,A2:A6)/SUM(B2:B6)
E(x^2f) =SUMPRODUCT(A2:A6^2,B2:B6)
E(xf)^2 =SUMPRODUCT(A2:A6,B2:B6)^2
E(f) =SUM(B2:B6)
Variance =B10-B11/B12
StDev =SQRT(B13/(B12-1))
Part 2: Chart Trickery
Data table:
Column D is just an incremental counter. This will be the number of data points in the normal distribution curve.
E2 =D2/$B$8 etc.
F2 =NORMDIST(E2,$B$9,$B$14,FALSE) etc.
Chart:
Now, add Columns E:F to the chart. You will need to massage a few things:
Change the series to be an X-Y plot. This might require some editing of the chart series to force a single series to use your desired X and Y values.
Change the series to use the secondary axes (both X and Y).
Change the secondary X-axis range to 0.5-5.5 (i.e., 0.5 on either side of the column chart category values). This will effectively align the primary and secondary X-axes.
Change the secondary Y-axis range to 0-1
Format the X-Y series appearance to taste (I suggest removing value markers).
The result so far:
Lastly, you can remove the tick marks and labels on the secondary axes to clean up the look.
Postscript: Thanks to John Peltier for innumerable charting inspirations over the years.

Resources