Upsample a graph and preserve the information - python

I have various length of time series data. Therefore I need to normalize it to be the same length first.
For example data_1 has 200 points with this shape
data_2 has 7000 points with this shape
data_3 has 3000 points
I had checked this. It does not work with my pulse shape. I lost significant information
Question:
How can I upsample to 9000 points and preserve the shape of them?

Looks like numpy's interp function does what you want:
import numpy as np
import matplotlib.pyplot as plt
x1 = np.linspace(0, 1, 10)
y1 = np.sin(2 * np.pi * x1)
x2 = np.linspace(0, 1, 30)
y2 = np.interp(x2, x1, y1)
plt.plot(x1, y1)
plt.plot(x2, y2, '.')
plt.show()

Related

I am trying to make a ARC diagram using python but I am not able to get the height uniform

I am trying to make an ARC diagram using matplotlib python. But I am not able to get the heights uniform ideally height = Radius/2. I am using scipy.intepolate to smoothen my curve. So I am not able to adjust my height as per the above-mentioned information ie 'height = Radius/2'.
I want my ARC to be uniform in height as shown in the figure in the link below:
https://datavizcatalogue.com/methods/images/top_images/arc_diagram.png
Below is the code I have used
import matplotlib.pyplot as plt
%matplotlib notebook
import numpy as np
from scipy import interpolate
count=[0,15,63,7,90,10]
y=[0,3,0]
plt.figure(figsize=(40,10))
x = [1,4,7]
start=x[-1]
for i in range(len(count)):
if i==0:
x = [1,4,7]
else:
x[0]=start
x[1]=x[0]+3
x[2]=x[1]+3
x2 = np.linspace(x[0], x[-1], 2000)
y2 = interpolate.pchip_interpolate(x, y, x2)
plt.plot(x2, y2,linewidth=(0.1+(count[i]/10)),color='green',alpha=0.6)
ax.append(x[0])
start=x[-1]
new_x=[x[0],x[-1]]
new_y=[y[0],y[-1]]
plt.plot(new_x,[0,0],color='grey',linewidth=5)
plt.plot(new_x,new_y,"o",color='grey',mew=10,ms=20)
plt.plot(new_x,new_y,"o",color='white',mew=10,ms=10)
Would greatly appreciate some help.
Thanks in advance.
You can draw a circular arc between two points using the following:
#!/usr/bin/env python
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import patches
# set the points
x1, y1 = (0., 0.)
x2, y2 = (1., 0.)
# calculate the arc
mxmy = mx, my = [(x1 + x2) / 2, (y1 + y2) / 2]
r = np.sqrt((x1 - mx)**2 + (y1 - my)**2)
width = 2 * r
height = 2 * r
start_angle = np.arctan2(y1 - my, x1 - mx) * 180 / np.pi
end_angle = np.arctan2(my - y2, mx - x2) * 180 / np.pi
# draw
arc = patches.Arc(mxmy, width, height, start_angle, end_angle)
fig, ax = plt.subplots(1,1)
ax.add_patch(arc)
ax.set_xlim(-0.1, 1.1) # you need to set the appropriate limits explicitly!
ax.set_ylim(-0.1, 1.1)
plt.show()
Shameless plug:
Some time ago, I wrote a little module that makes arc diagrams, specifically for comparing the connectivity in two networks (well, the same network at different time points, really). I am not using circular arcs but it may nevertheless be of interest as it does other things like minimize the number of crossings, etc. Also, it would be trivial to swap the function that draws the arc if you really, really wanted circular arcs. You can find the repo here.

find X-axis data points where horizontal line passes through on respective Y-axis value

I have a [1,2,3,4,5] data points on x-axis and its respective value on y-axis like [10,15,10,10,20].
normally to find value point of y-axis by given x-axis data points
like y=f(x), I checked this and we can achieve this by interpolation using numpy.. But I didn't found how to interpolate x-axis by given y-axis value.. as per attached screen I want to find respective x axis value where line 12 crosses..so I am expecting result something like [1, 1.x, 2, 2.x, 3, 4, 4.x, 5, 5.x] on x-axis
If it's a smooth curve, you can use InterpolatedUnivariateSpline
import numpy as np
from scipy import interpolate
x = np.linspace(0, 20, 100)
y = np.sin(x + 0.1)
y0 = 0.3
spline = interpolate.InterpolatedUnivariateSpline(x, y - y0)
xp = spline.roots()
Here is the plot:
pl.plot(x, y)
pl.axhline(0.3, color="black", linestyle="dashed")
pl.vlines(xp, 0, 0.3, color="gray", linestyle="dotted")
if you want linear interpolate:
x = np.linspace(0, 20, 20)
y = np.sin(x + 0.1)
y0 = 0.3
y_offset = y - y0
pos = np.where((y_offset[1:] * y_offset[:-1]) <= 0)[0]
x1 = x[pos]
x2 = x[pos+1]
y1 = y[pos]
y2 = y[pos+1]
xp = (y0 - y1) / (y2 - y1) * (x2 - x1) + x1
If you change interp1d(x,y) for interp1d(y,x) you have expressed x as a function of y.
Note that if f(x) is not unique, you may get unexpected or undefined behavior.

Spline interpolation over 3 variables for scattered data in Python?

With other words I got a set of data-points (x,y,z) associated to a value b and I would like to interpolate this data as accurate as possible.
Scipy.interpolate.griddata only can do a linear interpolation, what are the other options?
How about interpolating x, y, z separatly? I modified this tutorial example and added interpolation to it:
import matplotlib as mpl
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
import matplotlib.pyplot as plt
from scipy.interpolate import InterpolatedUnivariateSpline
mpl.rcParams['legend.fontsize'] = 10
# let's take only 20 points for original data:
n = 20
fig = plt.figure()
ax = fig.gca(projection='3d')
theta = np.linspace(-4 * np.pi, 4 * np.pi, n)
z = np.linspace(-2, 2, n)
r = z**2 + 1
x = r * np.sin(theta)
y = r * np.cos(theta)
ax.plot(x, y, z, label='rough curve')
# this variable represents distance along the curve:
t = np.arange(n)
# now let's refine it to 100 points:
t2 = np.linspace(t.min(), t.max(), 100)
# interpolate vector components separately:
x2 = InterpolatedUnivariateSpline(t, x)(t2)
y2 = InterpolatedUnivariateSpline(t, y)(t2)
z2 = InterpolatedUnivariateSpline(t, z)(t2)
ax.plot(x2, y2, z2, label='interpolated curve')
ax.legend()
plt.show()
The result looks like this:
UPDATE
Didn't understand the question at the first time, sorry.
You are probably looking for tricubic interpolation. Try this.

Plotting two different arrays of different lengths

I have two arrays. One is the raw signal of length (1000, ) and the other one is the smooth signal of length (100,). I want to visually represent how the smooth signal represents the raw signal. Since these arrays are of different length, I am not able to plot them one over the other. Is there a way to do so in matplotlib?
Thanks!
As rth suggested, define
x1 = np.linspace(0, 1, 1000)
x2 = np.linspace(0, 1, 100)
and then plot raw versus x1, and smooth versus x2:
plt.plot(x1, raw)
plt.plot(x2, smooth)
np.linspace(0, 1, N) returns an array of length N with equally spaced values from 0 to 1 (inclusive).
import numpy as np
import matplotlib.pyplot as plt
np.random.seed(2015)
raw = (np.random.random(1000) - 0.5).cumsum()
smooth = raw.reshape(-1,10).mean(axis=1)
x1 = np.linspace(0, 1, 1000)
x2 = np.linspace(0, 1, 100)
plt.plot(x1, raw)
plt.plot(x2, smooth)
plt.show()
yields
You will need two different x-axes for this job. You cannot plot two variables with different lengths in one single plot.
import matplotlib.pyplot as plt
import numpy as np
y = np.random.random(100) # the smooth signal
x = np.linspace(0,100,100) # it's x-axis
y1 = np.random.random(1000) # the raw signal
x1 = np.linspace(0,100,1000) # it's x-axis
fig = plt.figure()
ax = fig.add_subplot(121)
ax.plot(x,y,label='smooth-signal')
ax.legend(loc='best')
ax2 = fig.add_subplot(122)
ax2.plot(x1,y1,label='raw-signal')
ax2.legend(loc='best')
plt.suptitle('Smooth-vs-raw signal')
fig.show()

Data interpolation in python

I have four one dimensional lists: X1, Y1, X2, Y2.
X1 and Y1 each have 203 data points.
X2 and Y2 each have 1532 data points.
X1 and X2 are at different intervals, but both measure time.
I want to graph Y1 vs Y2.
I can plot just fine once I get the interpolated data, but can't think of how to interpolate data. I've thought and researched this a couple hours, and just can't figure it out. I don't mind a linear interpolation, but just can't figure out a way.
I think this is what you want:
import numpy as np
import matplotlib.pyplot as plt
# first data set
X1 = np.linspace(0,1,203)
Y1 = np.sin(X1)
# second data set
X2 = np.linspace(0, 0.5, 1532)
Y2 = np.cos(X2)
# get interpolated values of Y1 evaluated at X2
Y1_interp = np.interp(X2, X1, Y1)
# plot interpolated Y1 vs Y2
plt.plot(Y1_interp, Y2)
plt.show()
If you use matplotlib, you can just call plot(X1, Y1, 'bo', X2, Y2, 'r+'). Change the formatting as you'd like, but it can cope with different lengths just fine. You can provide more than two without any issue.

Categories