简体   繁体   中英

Detecting Curvature of a Plot

I have a data set that I am plotting. The result looks like the following image: 在此处输入图片说明

Here is my python code:

import numpy as np

# Extra plotly bits
import plotly
import plotly.plotly as py
import plotly.graph_objs as go

a = np.array([[1, 0.00617329], [24, 0.133699], [48, 0.130072], [72, 0.0166202], [96, -0.187917], [120, -0.445023], [144, -0.698984],
    [168, -0.942063], [192, -1.15151], [216, -1.30742], [240, -1.36852], [264, -1.33541], [288, -1.18194], [312, -0.982113],
    [336, -0.772301], [360, -0.562501], [384, -0.3764], [408, -0.219537], [432, -0.106257], [456, -0.0369356], [480, -0.000313192]])


trace_a = go.Scatter(
        x = a[:,0],
        y = a[:,1],
        mode = 'lines+markers',
        name = 'a',
        line = dict(
            shape='line',
            color = ('rgb(205, 12, 24)'),
            width = 1)
        )

data = [trace_a]

# Edit the layout
layout = dict(title = 'Curvature Test',
    xaxis = dict(title = 'Data'),
    yaxis = dict(title = 'Value'),
    )

# Prepare Figure
fig = go.Figure(data=data, layout=layout)

# Plot
plotly.offline.plot(fig, filename='curvature.html')

What I am trying to achieve is adding an additional plot that traces the curvature of the primary plot.

That probably will look like the following image: 在此处输入图片说明

(This is a prototype and the yellow markings are only to demonstrate that the second plot is representing the curvature of the first one.)

Since I was not able to find the right numpy/maths solution I prototyped this in an other environment using a dot product calculation of the previous and next tangent for each of the data points. So this is my "Poor-Man's-Curvature" solution:

在此处输入图片说明

How can I create a second data set that once plotted will represent the curvature of the primary one?

Disclaimer: I have asked this question before. However, did not manage to workout an elegant solution. I also have researched the topic of curvature and I am aware of the curvature calculations. Yet I am still struggling to put this together using python/numpy and the right mathematical approach. I also have spent some time on the following post but was not able to fully port the information provided there to solve my problem.

--- EDIT (1) ---

Here is the result of my solution: 在此处输入图片说明

the curvature can be interpreted as the second derivative so:

def derivative(x_data, y_data):
    N = len(x_data)
    delta_x = [x_data[i+1] - x_data[i] for i in range(N - 1)]
    x_prim = [(x_data[i+1] + x_data[i]) / 2. for i in range(N - 1)]
    y_prim = [(y_data[i+1] - y_data[i]) / delta_x[i] for i in range(N - 1)]
    return x_prim, y_prim

x, y = zip(*a)  # a in an array you defined above
x_bis, y_bis = derivative(*derivative(x, y))

but if you want to get curvature as curvature of 2D line on plane (not a curvature of function) you need to divide it by square root of third power of one plus squared derivative of y data ( (1+y'^2)^(3/2) ) :) just as in:

https://en.wikipedia.org/wiki/Curvature#Curvature_of_a_graph

probably you will need to make some interpolation, but if x-coordinates are equdistant - it would be much easier.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM