Python Build a multiple-column graph with matplotlib

1

I'm trying to make the chart with multiple parabolas. It's more of a help in mathematics.

    
asked by anonymous 17.09.2018 / 13:44

2 answers

0

Graphics in matplotlib require numeric series already filled in NumPy array -

So you can write a function that only cares about the mathematical part itself, taking an 'x' per input, and generating a 'y' that works at the desired intervals, and then it is easy to fill the numerical series with the numpy using your function.

So, thinking of the function - you want periodic intervals to create "head-up parabolas" with a narrow aperture, and that below a certain threshold for the parabola values, the value of the function is constant.

Interesting here is that the function then will not only get "x" and give you a "y" - it has configuration values - one way to do this is a function inside another - the outside receives the parameters of "threshold", "interval" and "aperture" - and the inside is a function that only receives an ordinate "x" and returns "y". This would not be "necessary" - you can do with a normal only function that receives x and the other three parameters - but then, you have to put some extra logic in the time to generate the values of "y" - since the ways of doing this with numpy usually takes only one parameter.

So let's have something of the form:

def parametrizar(periodo=100, limite=0, abertura=20):
    def f_x(x):
        # código que usa os 3 parâmetros acima para realmente calcular y
        ...
        return resultado
    return f_x
Now, as for the function itself - first the easiest to solve seems to be the "period" - just take the rest of the division of x for the desired period - but I realize that besides that it will be nice to have a shift too - then the first desired peak is "50" with a period of 200, we normalize these values - so that the center of the parabola is "50" and we take the rest of the division by "200" - doing step by step: >
def parametrizar(deslocamento=50, periodo=100, deslocamento_y=1, limite=0.0, abertura=6):
    limite = float(limite)
    def f_x(x):
        # repete valores de x períodicamente:
        x1 = x % periodo
        # deixa que a abcissa seja '0' onde desejamos o pico
        x2 = x1 - deslocamento
        # escala o valor "x" antes de elevar ao quadrado de forma
        # que os valores para "abertura" sejam mais razoaveis:
        x3 = x2 / periodo

        # calcula a parábola em si:
        y = - abertura * (x3 * x3) + deslocamento_y
        # limita os valores baixos ao patamar desejado:
        if y < limite:
             y = limite 
        return y
    return f_x

And that works. Now just create an array with the numbers y, and use np.vectorize to apply the function - and the parameters can be modified until the final plot is appropriate for what you need:

import numpy as np
import matplotlib.pyplot as plt 
x = np.arange(0, 500,0.1, dtype=np.float64)

fx = parametrizar(abertura=30, limite=0.5)
y = np.vectorize(fx)(x)

plt.plot(x, y); plt.show()
    
18.09.2018 / 00:03
0

To construct parabolas I like to use exponential function , basically its parable is a Gaussian function , why do I like exponential function (exp) ? simply because I can control where the parabola will be centered in addition to controlling the width of the window ... to demonstrate I've created a vector (dados) size 1200 , in some positions I added "peaks"

dados = np.zeros(1200)

dados[70] = 0.9
dados[290] = 0.9
dados[505] = 0.9
dados[720] = 0.9
dados[1000] = 0.9

The rest of the vector is composed of zeros, plot of the vector dados :

SonowIwanttoinsertaparabolaintoeachofthosepeaks...

Icreatedanauxiliaryvectortohelpmefindtherelativeexponentialvalueoftheparabola:

x=np.linspace(0,1,len(dados))

TheVectorisspacedby1andhasthesamesizeastheinputvector,nowcomesthecoolpartofthegame,createtheparabolainthepositionsoftheaboveplotpeaks:

np.exp(-np.power(x-pos,float(2.))/(2*np.power(lenKernel,float(2.))))

TheabovefunctioncalculatesaGaussianfunction(parabola):

x=vetorauxiliarlenKernel=larguradajanelapos=posiçãoondeaparábolaserácentrada

Nowyoucanaddthisfunctiontoeverynecessarypeak,theoutputofmycodeproducesthefollowingplot:

Complete code:

import numpy as np
import matplotlib.pyplot as plt



dados = np.zeros(1200)

dados[70] = 0.9
dados[290] = 0.9
dados[505] = 0.9
dados[720] = 0.9
dados[1000] = 0.9

lenKernel =0.020

y=0;

x= np.linspace(0, 1, len(dados))

for i in [(70), (290), (505), (720), (1000)]:
        pos=i/float(len(dados))
        y=np.exp(-np.power(x - pos, float(2.)) / (2 * np.power(lenKernel, float(2.)))) + y






plt.plot(dados)

plt.plot(y)


plt.show()
    
18.09.2018 / 03:45