DataThief is a nifty Shareware utility for extracting the coordinates from an image of a graph. After a plane is defined (by marking three coordinates on the picture), one can mouse over the graph to find the numerical coordinates of each points.
Can it be automated? Online documentation seems to be nil.
Follow the color method
First, open up the picture in DataThief.
I found it helpful to zoom in (Action Menu).
Next, I set the coordinates of some reference points on the graph, by moving the colored crosshairs.
The vertical red/green rectangle is a progress bar relating how fit, squared, orthogonal the reference points are.
I placed the Start, Color, and End markers, choose Trace (Action Menu), and then Export (File Menu).
The result was a tidy text file with my data points. Great! Now to capture some useful data.
Scatter plot method
Tracing a continuous graph appears to be just one (the upper right button) of DataThief's four data acquisition modes. Let's match the data points via the scatter plot option (lower right button). Drag the crosshairs from the gray box over each data point.
I am interested in automating this process for a graph with hundreds of data points?
I clicked on the Settings tab, fiddled with some options, and got the next graph via the Show button.
Good, the data are points can be isolated via color recognition.
The question
How do I automate the selection of an arbitrary number of points?
Related
For a game that's similar to Qix, Volfied, Paper.io and splix.io, where you need to encircle an area to capture it, I'm struggling to find proper way for AI to detect valuable territory features to capture.
The image below presents 9 examples of territory fragments of a bigger map, where the blue color is territory owned, black color is empty area that need to be captured, green and white points need to be calculated, so AI could pass through them to actually capture territory.
This can also be formulated as: how to find shortest path that encircles as much of empty area as possible?
Maybe a contour tracing algorithm could be used??
This is more a math question than a programming question beside the fact that I must implement it using Delphi inside a graphic application.
Assuming I have a picture of a sheet of paper. The actual sheet of paper is of course a rectangular area. When the picture is shown on a computer screen the rectangular area is no more rectangular because when the picture was taken, the camera was not perfectly positioned above the sheet of paper. There is all kinds of perspective effects which result in deformations.
My application needs to tweak the image so that the original rectangular area is displayed as a rectangular area on screen.
Most photo processing software have an interactive tool to do that. The user draw a rectangular area on screen around the rectangular object and then drag each corner to deform the displayed rectangular area until he see the real area as rectangular. What I'm looking for is the algorithm to do that computation.
You need to split the problem into 2 steps. Find the edges or corners of the sheet and remap the pixels.
To find the corners or edges it's a really hard problem since they might be invisible, outside of the picture, obstructed, bent or deformed. Assuming you have a very simple setup (black uniform background, white paper, very little distortion) you could run an edge detection kernel over the image then find the 4 outer edges. If you find the edges you can intersect them to find the corners and the other way around.
Once you find the corners run an interpolation over the image to map the pixels onto the rectangle you want. You should be able to get the graphics engine to do this for you if you provide the coordinates of the corners as texture coordinates for the rectangle and map the image as a texture.
I made it sound simple, but you will encounter many parameters to set and experiment with.
It seems (because you mentioned bilinear interpolation) that you need perspective transformations.
There is implementation of perspective transformations (mapping of arbitrary convex quad to rectangle and vice versa) in Anti-Grain Geometry library (exe example). Delphi port.
With agg_trans_perspective one can calculate the matrix of persp. transformation and then apply it to map coordinates from one quad to another.
Let's say I have a standard tiled map like this: http://bl.ocks.org/mbostock/4132797
How can I get the bounding box coordinates of the visible map?
In other words, how can I say exactly the extent of the map shown at any given time. I understand this as a bounding box but also as an extent.
Thank you.
I was able to find answers to similar but specific questions but am leaving this up in case someone is searching for the general case.
From Elijah Meeks's answer:
To find the bounding box of the visual area of your map on screen,
simply use the projection.invert() function and feed it the top-left
and bottom-right corners of your SVG. If you have a 500x500 SVG, then
that looks like this:
projection.invert([0,0]) projection.invert([500,500]) This is a
bounding box of your screen, in lat-long (or whatever coordinate
system you're using).
After that, you can get the bounds of your features and test to see if
they are fully-contained or intersecting or have their centroid within
those bounds. I'm not going to explain how to do that here, because
that's a different question with many different answers depending on
which definition of "within these bounds" you decide on.
So, plug in the width and heightof the visible area into the projection generator. Voila, you have the box.
I have a sunburst code here: http://plnkr.co/edit/EG0MzWEPB242g7VdSQQd?p=preview
When I click the orange area that corresponds to "from tumor cell" (see the caption below in the diagram), I get focussed diagram centered on "from tumor cells".
When I mouseover the area in the region marked "Liver or Pancreas", the texts in the caption box below changes while it should not. I suppose this problem is only in the second and third quadrant (90 degree to 270 degree). I couldn't find a way to solve this problem after spending so much time.
I hope some one has an answer to it.
The problem is that you're attaching the mouse over handlers to the g element, which isn't updated when you click on a segment. The easy way to fix this is to attach the handlers to the path elements, which do get updated, instead. In that case you probably also want to set the text elements to receive no pointer events so that there are no spurious mouse events when moving over them.
Complete demo here.
So I am using jqPlot to display distance (y-axis) over time (x-axis) in a simple line graph.
However, while I have actual distances as the underlying data used to position the points, I'm not interested in displaying those distances on the y-axis.
Instead, there are a series of landmarks at given distances, that I want to appear on the y-axis as a 'tick' next to the appropriate point for the distance to that landmark. That way the line appears to "pass" each landmark as it travels upward.
Currently I'm "faking" this by hiding the ticks and putting a manually-created series of labels next to the graph. This works well enough, but I had to disable vertical zooming because if the user chose to zoom in, the labels would not match up with the actual distances. My users would really like to zoom in vertically, however, and I want to allow them to.
Therefore, does anyone know of a way (a plugin or similar) that would allow me to associate custom labels with given tick marks in jqPlot, that will match up nicely and respond to zooming? It would be necessary to hide some of the landmarks if the graph is zoomed out too much, so that would have to be a feature.
Alternatively, if someone knows of a "zoom event" that passes in the min and max y values, I could probably recreate my manual labels with that data, so let me know if you know of a way to get that information. I haven't been able to find one.
I would need to see a bit of your code to customize it to the distance but to start with you could label the ticks and it will display over the size of the chart.
axes:{yaxis:{ticks:['DiscanceA','DiscanceB', 'DiscanceC', 'DiscanceD', 'DiscanceE'],
renderer: $.jqplot.CategoryAxisRenderer,},
Let me know how it goes and if you have any code lets see it!