2013-07-01 12 views
5

Chciałbym wykreślić wykres niektórych danych eksperymentalnych, które są próbkowane ze stosunkowo dużą szybkością, ale przybliżają gładką krzywą za pomocą znaczników rozmieszczonych w równych odstępach długości łuku, jak pokazano na poniższym wykresie:Wykreślanie krzywej z równoodległymi znacznikami długości łuku

Graph with equal arc-length markers

wiem o markevery argumentem inwestycyjnym, ale że grono się znaczniki na prawo od działki i prawdopodobnie mają dość kilka markerów po lewej stronie. Rozwiązanie powinno być niezależne od skal na osiach xi y. Jestem otwarty na instalowanie dodatkowych modułów, ale powinien to być system python + matplotlib.

+0

Czy masz algebraiczną formułę tej krzywej/funkcji? Myślę, że jest to potrzebne, abyś mógł użyć swoich pochodnych do obliczenia długości łuku (najprawdopodobniej z iteracyjnym rozwiązaniem). – heltonbiker

+0

Nie, jak wspomniałem, krzywa jest wynikiem eksperymentu. Liczbowe aproksymacje pochodnej powinny być jednak w porządku, chociaż przy pomiarze jest niewielki hałas, mogę go łatwo wyrównać. – chthonicdaemon

Odpowiedz

2

Myślę, że zebrałem stosunkowo dobre rozwiązanie. Jedynym problemem jest uwzględnienie współczynnika danych w sposób, który również wykorzystuje informacje o współczynniku kształtu końcowego wydruku. Nie znalazłem niezawodny sposób, aby to zrobić, chociaż ta funkcja będzie akceptować stosunek danych, dzięki czemu można grać aż wyjście wygląda prawo:

def spacedmarks(x, y, Nmarks, data_ratio=None): 
    import scipy.integrate 

    if data_ratio is None: 
     data_ratio = plt.gca().get_data_ratio() 

    dydx = gradient(y, x[1]) 
    dxdx = gradient(x, x[1])*data_ratio 
    arclength = scipy.integrate.cumtrapz(sqrt(dydx**2 + dxdx**2), x, initial=0) 
    marks = linspace(0, max(arclength), Nmarks) 
    markx = interp(marks, arclength, x) 
    marky = interp(markx, x, y) 
    return markx, marky 

Przykład zastosowania (to jest odpowiedni dla trybu pylab w ipython) :

x = linspace(0, 10*pi, 1000) 
y = sin(x*2) + sin(x+1) 

plot(x, y) 
markx, marky = spacedmarks(x, y, 80) 
plot(markx, marky, 'o', color='blue') 

Wynik:

Sample output showing equally spaced markers

+1

Powiązany problem z 'matplotlib' wymieniający odstępy między znakami kręgu jako pożądaną funkcję: https://github.com/matplotlib/matplotlib/issues/346 –