Anychart Polar Plot line performance - javascript

I was trying to draw a polar plot using the Anychart library and I found a strange behavior that I wanted to share. I wanted to draw a polar plot with a number of points that are linked with a line representing different angles. The strange behavior I saw is that sometimes the line belongs to the "shortest path" between points and sometimes belongs to the "longest path", connecting the dots always in a "clockwise" direction.
In my brain, the line should go "clockwise" when increasing the angle (for instance, moving from 45º to 135º) and "counterclockwise" when decreasing the angle (for instance, moving from 135º to 45º).
My question is, is there an option to decide the direction of the line connecting the dots? I have done a test here with the "Anychart" playground option to show this scenario (https://playground.anychart.com/F6srRlRo/12). The "always-clockwise" performance can be seen in the upper left plot, while the desired performance, achieved by dividing the lines into 3 different line series, can be seen in the upper right plot. The problem of the solution I found is that, for longer datasets, depending on the data it might be required to use thousands of different series, which lowers considerably the rendering time of the plot (this can be seen in the lower left and lower right plots, where the left one is faster, but is "always-clockwise" and the right one is slower, but as desired).
any help in how to improve rendering time or plot everything in one simple Line data series?

Related

Algorithm to decompose Polygons into lineStrings (Headlands from Plots)

Consider the following polygon (an agricultural plot)
From this polygon, I would like to extract the "headlands" of the plot, being the consecutive lines (sides) of the polygon (Wikipedia) used for turning on the field. While often only the rows running perpendicular to the lay of the field are considered, I need all sides of the polygon.
Here, a consecutive line means any set of coordinates, where the angle between any two coordinates of the set is not larger than a value X (e.g 30 degrees).
For the given example, the resulting headlands should look like the following:
I wrote a small algorithm trying to accomplish this, basically checking the angle between two coordinates and either pushing the given coordinate to the existing lineString if the angle is below X degrees or creating a new lineString (headland) if not.
Check out the following Gist
However, in some cases corners of a field are rounded, therefore may consist of many coordinates within small distances of each other. The relative angles then may be less than the value X, even though the corner is too sharp to actually be cultivated without turning.
In order to overcome that issue, I added an index that increases whenever a coordinate is too close for comparison, so that the next coordinate will be checked against the initial coordinate. Check out the following Gist.
This works for simple plots like the one in the example, however I am struggling with more complex ones as the following.
Here, the bottom headland is recognised as one lineString together with the headland on the right, even though optically a sharp corner is given. Also, two coordinates in the upper right corner were found to be a separate headland even though they should be connected to the right headland. The result should therefore yield in the following:
What I would like to know is if there is an approach that efficiently decomposes any polygon into it's headlands, given a specific turning angle. I set up a repo for the code here, and an online testing page with many examples here if that helps.

d3 Best practices to visualize data?

I am working on a project where data points are visualized in the scatterplot using d3. Since it is a web application, the region is limited and a lot of points overlap. In total there are 20k points and I allow users zooming in with a brush (and its extent) on regions, but even when zoomed in there is still a huge overlap of points. An example of such a situation:
What are good approaches to still visualize underlying points, to enhance the view or perception of the points? I was thinking about maybe using transparency, but I do not know if that would do it.
It might be worthy to note that all points represent genes, so clustering them may not be very logical in terms of representation.
I would suggest trying d3's fisheye plug-in. It allows you to zoom and distort the scale with the mouse letting you zoom in on areas.
You can see an example of it used with a scatter/bubble chart lower on the page here: http://bost.ocks.org/mike/fisheye/
In addition, if you have overlap I would increase opacity, so you can see which points have lots of overlap vs. points that don't.
Here's an example graph with very clustered points that I created using both fisheye and opacity: http://crclayton.com/projects/fisheye/
It also allows you to hover over individual points to see a tooltip containing more details about them.
If the number of data points is of interest, then you could cluster the points (either on client/server side). You typically see this pattern if maps have too many markers (example cluster map).
Edit:
I am still not quite sure if I'm heading in the right direction. To visualize the quantity of points you could use a 3D visualization. Here is an idea taken from the Software Cities project:
You could basically render the position of the points on the plane and create vertical cylinders - the more points on the same spot, the higher the cylinder.

Violin chart in D3

Any ideas on where to even begin with making a violin chart using d3? Does it exist already?
I've looked around and have figured out how to do it using ggplot2 and was hoping there'd be a ready-made example that I could learn from but haven't found one yet.
I suppose I could do a really painful process of making various size bars on top of each other, or taking a distribution, rotating it and mirroring it. But surely there's a better way.
I needed that for myself so here it is: violin plot
As far as I know, nobody has done this before, but it shouldn't be too hard. I would start as if I was making a line chart (or boxed instead of lines) for one half of a violin. That is, create the appropriate x and y scales and add the data in. The result of this I would rotate and translate to the correct position. Then do the same thing again and mirror it as well to get the other half of the violin.
This may sound complex, but SVG has built-in support for these operations (rotating and mirroring). You should be able to approach this pretty much like drawing a line graph of the distribution with 2-3 simple operations on top of that. Wrap everything in a function and you've got something you can call to create a violin.
It of course also depends in what form you have the data to make the plot. A line plot might not be feasible because of too few data points, but then you can easily use bars instead.

How to scale a multi-line Google chart to have maximums at the same height?

I'm using Google Chart API to display a multi-line chart in my application. The graph shows daily income in several currencies.
As you can see, there is a problem when the exchange rate between the currencies is significant (20 CZK = 1 USD). You may notice the little bump at about 1 third. That's actually 18 USD which is (when the exchange rate is taken into account) about 360 CZK.
I need to scale the lines to have their maximums at the same height.
I know I could just use a multiplication mapper but then there would be wrong values in tooltips shown on hover.
What solution would you recommend? I really don't like the idea of rendering the graph on my own. Thanks.
So, what you basicly need is three different Y axes.
I would do it by rendering three graphs side by side,
or three transparent graphs absolutely positioned in one space, if it were possible to render the axes nicely.
or using different units for higher exchange rates (maybe hundreds CZK)

Plotting mathematical functions without rendering artefacts

I don't think there's a good answer to this, but I'd like to find out if there's a better way to do this.
I need to plot a mathematical function, which is nearly flat at one end of the display, and nearly vertical at the other end. The bottom left quadrant of a circle would be a good model. I can auto-generate as many points as required.
The problem is, I can't do this without all sorts of artefacts.
I haven't tried Bezier fitting; I don't think this would be even close. My understanding is that Bezier is for one-off manually-constructed pretty graphics, and not for real curve-fitting.
That leaves polylines. There are only 2 things I can do with polylines - I can select the line length (in other words, the number of points I auto-generate), and I can disable anti-aliasing (setAttributeNS(null, "shape-rendering", "crisp-edges").
If I generate lots of points, then I get jaggies everywhere, and the result is unusable. It can also look very much like it's oscillating, which makes it appear that I've incorrectly calculated the function. The anti-aliasing doesn't make any difference, since it doesn't operate across point boundaries.
The only solution I've got is to draw fewer points, so that it's obvious that I'm drawing segments. It's no longer smooth, but at least there are no jaggies or oscillation. I draw this with the default anti-aliasing.
Any ideas?
Edit:
It seems like the only answer to this is actually Bezier curve fitting. You have to preprocess to find the parameters of the required segments, and then plot the results. Google comes up with a number of hits on curve fitting with Beziers.
You have the mathematical function, and can therefore generate as many points as you need.
I assume the problem is that because you do not know the output resolution (SVG is device independent) you do not know how many points to generate. Otherwise you could just create a polyline where each line is approximately 1 pixel long.
Fitting your mathematical function to a bezier curve is (probably) not going to get a perfect match - just like a circle cannot be matched perfectly by a cubic bezier curve. And I think the task of fitting your function to a bezier curve would not be trivial (I've never done this).
Could you rather output your mathematical function to a canvas element? Then you could write some javascript code to plot your mathematical function dependant on the output resolution. Similar to how a graphics system renders a Bezier curve.
Do you know how graphics systems render Bezier curves? They approximate the bezier curve with a polyline, and then measure the error difference between the polyline and the bezier curve. If the difference is greater than a certain tolerance - where the tolerance is determined by the output resolution - the bezier is subdivided and the process repeated for each bezier curve. When the difference between beziers and polylines is below the tolerance, the polylines are drawn. http://en.wikipedia.org/wiki/B%C3%A9zier_curve#Computer_graphics
I suppose you want to draw y=f(x) over a certain interval [a,b]
A classical solution is to take N points uniformly distributed over [a,b], to compute f over these points and draw lines (or polynoms).
It of course doesn't work in your case, since y is nearly vertical in certain area. But why don't you take more points in these areas (and less points where the function is nearly horizontal) ?
You can compute the derivative of your function (or approximate this derivative with (f(x+h)-f(x))/h and h small) and determine the step between two successive points with this derivative

Categories

Resources