2016-07-20 9 views
2

Ich verwende ein Programm auf einem Raspberry Pi, das die Spannung an einer Sonde in Salzwasser misst, um den Salzgehalt des Wassers zu berechnen. Die Beziehung ist nicht linear, sondern wird zu einer ziemlich geraden Linie, wenn eine Potenztrendlinie in einem logarithmischen Plot gezeichnet wird. Dies bedeutet, dass die Sonden mit nur zwei Werten kalibriert werden könnten und einfach eine gerade Linie zwischen ihnen interpolieren könnten, wenn sie in einem logarithmischen Diagramm gezeichnet werden.Interpolation einer geraden Linie in einem logarithmischen Diagramm (NumPy)

Salinity graphs

Leider ist das bereits bestehende Programm angenommen eine lineare Beziehung Standardachsen mit und ich bin nicht sicher, wie es zu ändern, für eine gerade Linie auf einer log-log Plot zu interpolieren. Jede Hilfe wäre willkommen, bitte beachten Sie, dass dies das erste Stück Code ist, das ich gemacht habe, so dass mein Wissen nicht großartig ist. Ich habe Bits des Codes enthalten, die die Interpolation unter beinhalten:

import smbus 
import time 

# imports for plotting 

import numpy as np 
import matplotlib.pyplot as plt 
import scipy.interpolate 

# do the first plot - all values zero 

nprobe=4 

x=np.array([10.0, 30.0, 10.0, 30.0]) 
y=np.array([10.0, 10.0, 20.0, 20.0]) 
z=np.array([0., 0., 0., 0.]) 

# changing probe 1 to my handmade probe 1 
fresh=np.array([0.,0.,0.,0.]) 
sea =np.array([100.0,100.0,100.0,100.0]) 
range=np.array([100.0,100.0,100.0,100.0]) 
range=1.0*(sea-fresh) 


# grid for plots - 20 is a bit coarse - was 100 give explicit (0,1) limits as no bcs here 
########### xi, yi = np.linspace(x.min(), x.max(), 50), np.linspace(y.min(), y.max(), 50) 
xi, yi = np.linspace(0, 1, 50), np.linspace(0, 1, 50) 
xi, yi = np.meshgrid(xi, yi) 

rbf= scipy.interpolate.Rbf(x,y, z, function='linear') 
zi= rbf(xi, yi) 

plt.ion() 

tank=plt.imshow(zi, vmin=0, vmax=50, origin='lower', extent=[0, 44, 0, 30]) 

plt.scatter(x, y, c=z) 
plt.colorbar() 

plt.draw() 

Auch später im Programm:

# make r1 an array, results between 0-100 where 0 is 0% salinity and 100 is 2.5% salinity 
     z=100.0*(r1-fresh)/range 

     print time.strftime("%a, %d %b %Y, %H:%M:%S") 
     print "measured reading at above time (r1)" 
     print r1[0],r1[1],r1[2],r1[3] 
     print "fresh values used for calibration" 
     print fresh 
     print "range between calibration values" 
     print range 
     print "percentage seawater (z)" 
     print z 

# interpolate 
     rbf= scipy.interpolate.Rbf(x,y, z, function='linear') 
     zi= rbf(xi, yi) 
# alt interpolate 
#########  zi=scipy.interpolate.griddata((x,y), z, (xi,yi), method='linear') 

     print "zi" 
     print zi 

Antwort

0

Wie wäre es

import numpy as np 
import scipy 
import scipy.interpolate 

import matplotlib.pyplot as plt 

def log_interp1d(x, y, kind='linear'): 
    """ 
    Returns interpolator function 
    """ 
    log_x = np.log10(x) 
    log_y = np.log10(y) 
    lin_int = scipy.interpolate.interp1d(log_x, log_y, kind=kind) 
    log_int = lambda z: np.power(10.0, lin_int(np.log10(z))) 
    return log_int 

powerlaw = lambda x, amp, index: amp * (x**index) 

num_points = 20 

# original data 
xx = np.linspace(1.1, 10.1, num_points) 
yy = powerlaw(xx, 10.0, -2.0) 

# get interpolator 
interpolator = log_interp1d(xx, yy) 

# interpolate at points 
zz = np.linspace(1.2, 8.9, num_points-1) 
# interpolated points 
fz = interpolator(zz) 

plt.plot(xx, yy, 'o', zz, fz, '+') 
plt.show()