Closed davidfokkema closed 9 years ago
The function in question: _calc_position_for_pin
The problem is in:
x0, x1 = x[0], x[-1]
xs = relative_position * (x1 - x0) + x0
Because if the start and end x values are equal you always get xs = x0
.
So relative position assumes the x values are continuously increasing/decreasing values.
The question is, what should we assume about the spread of/steps between the data points? And should relative_position
be relative to the data points or to the start/end value of the data.
For example: if x = [0, 1, 3]
, should relative_position = .5
mean x value 1 (half way through the data points) or x value 1.5 (half way between the start and end points)?
And relative_position = .6667
would be something like this (if y = x
):
l1 = len(x) - 1
idx = int(l1 * relative_position)
part = idx / float(l1)
x0 = x[idx]
x1 = x[idx + 1]
xs = (relative_position - part) * (x1 - x0) + x0
ys = np.interp(xs, x, y)
# ys = 1.334
This should work fine for cricles and ellipses.
However, it would work best/most predictable if the length of the paths between data points is evenly distributed.. The problem is that you can not easily determine the speed
at which the data moves from one point to the next..
It's hard to think of one solution for all cases..
Yes, it's hard! Nice summary. Ideally, it should be (in my opinion) halfway along the path. But then you must know the path length. That may be approximated by piecewise linear interpolation, since the path is usually drawn with linear segments.
Total length is 'easy'
length = sum(sqrt((x[i] - x[i - 1]) ** 2 + (y[i] - y[i - 1]) ** 2)
for i in range(1, len(x)))
But then you need to find the point where you are at a fraction (relative_position) of that length.. Perhaps numpy.cumsum can help..
See #23. Is that what you had in mind?
This is exactly what I had in mind. Nice implementation, as well!
Fixed by #23. (Only need to decide on handling for log plots)
If you try to plot a circle or ellipse, and add a pin at
relative_position=.5
, the x-coordinate is interpolated and that value is used to interpolate the y-coordinate. The resulting value for y, however, is the first one in the series and not halfway in the series. The pin ends up at the wrong spot. We need to fix this.