I want to change x axis scale. For example, I am reading a data from txt file.
This data is like a=[ 1,2,5,9,12,17] and I want to convert to this number this scale[0,3]. I mean this data a=[ 1,2,5,9,12,17] has 6 number but I need to scale these number in [0,3] so that my axis should only be c=[0,3].I have other data c=[1,2,3,4,5,6]. I plot this data in normal way plot(a,b) but I want to scale this like plot(c,b). I don't know which function I will use for that.
Other question, I used plt.axhline(y=0.005), I want to change with linestyle='-' because otherwise giving continues line. How can I put max and minimum threshold with '-' ?
Second question answer:
import matplotlib.pyplot as plt
plt.axhline(y=0.5, color='b', linestyle='--',linewidth=1)
plt.axhline(y=-0.5, color='b', linestyle='--',linewidth=1)
plt.show()` I solved my second question like this.
If NumPy is available you can use the interp function to generate your scaled values (docs):
import numpy as np
scaled_a = np.interp(a, (min(a), max(a)), c)
The scaled_a variable is a NumPy array that can be passed to matplotlib's plot function in place of the original a variable.
If NumPy is not available you'll have to do a bit of arithmetic to calculate the new values:
def scaler(x, old_min, old_max, new_min, new_max):
old_diff = old_max - old_min
new_diff = new_max - new_min
return ((x - old_min) * (new_diff / old_diff)) + new_min
old_min = min(a)
old_max = max(a)
scaled_a = [scaler(x, old_min, old_max, c[0], c[1]) for x in a]
The variable scaled_a is now a python list, but it can still be passed to the plot function.
Related
I got a simple 2D array of values like this :
[simple array]
and I want to add reverb to it (I don't know how to call it other way) in order for it to look like this, basicly with a damping/smooth effect on y values but only on +x :
[with reverb]
I tried to check with scipy as i'm already using it to smooth values but didn't found out how to do it.
does anybody has an idea ?
You could try a Finite impulse response filter, though it's not clear if it's exactly what you need.
This was produced by the script below.
I've assumed, given your figures, that your data is actually 1-dimensional (a "line" of numbers, not a "rectangle").
import numpy as np
import matplotlib.pyplot as plt
from scipy import signal
npts = 50
# FIR with falling sawtooth impulse response
b = np.linspace(1,0,npts,endpoint=False)
u = np.zeros(3 * npts)
u[0] = 1
u[npts + 10] = 1
u[npts + 10 + npts//2] = 1
y = signal.lfilter(b, [1], u)
fig, ax = plt.subplots(2)
ax[0].stem(u)
ax[0].set_ylabel('input')
ax[1].stem(y)
ax[1].set_ylabel('output')
plt.show()
hi trying to plot the graph of the results from a while loop but keeps returning an empty graph and saying there is a value error
#create function f(n)
def f(n):
if (n % 2)==0:
return n/2
else:
return (3*n+1)/2
#loop funtion
q=63
while q != 1:
q=f(q)
#plot the function
import numpy as np
import matplotlib.pyplot as plt
i=np.linspace(0,10,3)
plt.plot(q,i)
plt.show()
It might be helpful to properly indent the code as it's is easier to interpret :)
The reason you got value error was because the dimensions of your x and y values are dissimilar. While for x you were passing a variable of size 1, for y you are passing an array of size 3. Furthermore, when using matplotlib's plot function, it's advised to specify the attributes of the plot function which determine the kind of plot you want (otherwise it can output an empty plot). I have inputted example values in the revised code below.
Hope this helps in achieving your main goal of plotting the function!
import numpy as np
import matplotlib.pyplot as plt
def f(n):
if (n % 2)==0:
return n/2
else:
return (3*n+1)/2
#loop function
q=63
while (q != 1):
q=f(q)
#plot the function
i=np.linspace(0,10,3)
#Here i is an array of type float of size 3, so you need to pick one of the
#values in i to plot with the value of q(which is a float variable of size 1)
plt.plot(q, i[2], color='green', marker='o')
plt.show()
I was plotting a scatter plot to show null values in dataframe. As you can see the plt.scatter() function is not expressive enough. Relation between list(range(0,1200)) and 'a' is not clear unless you see the previous lines. Can the plt.scatter(x,y) be written in a more explicit way where it could be easily understood how x and y is related. Like if somebody only see the plt.scatter(x,y) , they would understand what it is about.
a = []
for i in range(0,1200):
feature_with_na = [feature for feature in df.columns if df[feature].isnull().sum()>i]
a.append(len(feature_with_na))
plt.scatter(list(range(0,1200)), a)
On your x axis you have the number, then on the y-axis you want to plot the number of columns in your DataFrame that have more than that number of null values.
Instead of your loop you can count the number of null values within each column and use numpy.broadcasting, ([:, None]), to compare with an array of your numbers. This allows you to specify an xarr of the numbers, then you use that same array in the comparison.
Sample Data
import pandas as pd
import numpy as np
import matplotlib.pyplot as plot
df = pd.DataFrame(np.random.choice([1,2,3,4,5,np.NaN], (100,10)))
Code
# Range of 'x' values to consider
xarr = np.arange(0, 100)
plt.scatter(xarr, (df.isnull().sum().to_numpy()>xarr[:, None]).sum(axis=1))
ALollz answer is good, but here's a less numpy-heavy alternative if that's your thing:
feature_null_counts = df.isnull().sum()
n_nulls = list(range(100))
features_with_n_nulls = [sum(feature_null_counts > n) for n in n_nulls]
plt.scatter(n_nulls, features_with_n_nulls)
I need to obtain the fourier transform of a complex field. I'm using python.
My input is a 2D snapshot of the electric field in the xy-plane.
I currently have a 3D array F[x][y][z] where F[x][y][0] contains the real component and F[x][y]1 contains the complex component of the field.
My current code is very simple and does this:
result=np.fft.fftn(F)
result=np.fft.fftshift(result)
I have the following questions:
1) Does this correctly compute the fourier transform of the field, or should the field be entered as a 2D matrix with each element containing both the real and imaginary component instead?
2) I entered the complex component values of the field using the real multiple only (i.e if the complex value is 6i I entered 6), is this correct or should this be entered as a complex value instead (i.e. entered as '6j')?
3) As this is technically a 2D input field, should I use np.fft.fft2 instead? Doing this means the output is not centered in the middle.
4) The output does not look like what I'd expect the fourier transform of F to look like, and I'm unsure what I'm doing wrong.
Full example code:
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import cm
x, y = np.meshgrid(np.linspace(-1,1,100), np.linspace(-1,1,100))
d = np.sqrt(x*x+y*y)
sigma, mu = .35, 0.0
g1 = np.exp(-( (d-mu)**2 / ( 2.0 * sigma**2 ) ) )
F=np.empty(shape=(300,300,2),dtype=complex)
for x in range(0,300):
for y in range(0,300):
if y<50 or x<100 or y>249 or x>199:
F[x][y][0]=g1[0][0]
F[x][y][1]=0j
elif y<150:
F[x][y][0]=g1[x-100][y-50]
F[x][y][1]=0j
else:
F[x][y][0]=g1[x-100][y-150]
F[x][y][1]=0j
F_2D=np.empty(shape=(300,300))
for x in range(0,300):
for y in range(0,300):
F_2D[x][y]=np.absolute(F[x][y][0])+np.absolute(F[x][y][1])
plt.imshow(F_2D)
plt.show()
result=np.fft.fftn(F)
result=np.fft.fftshift(result)
result_2D=np.empty(shape=(300,300))
for x in range(0,300):
for y in range(0,300):
result_2D[x][y]=np.absolute(result[x][y][0])+np.absolute(result[x][y][1])
plt.imshow(result_2D)
plt.show()
plotting F gives this:
With np.fft.fftn, the image shown at the end is:
And with np.fft.fft2:
Neither of these look like what I would expect the fourier transform of F to look like.
I add here another answer, suitable to the added code.
The answer is still np.fft.fft2(). Here's an example. I modified the code slightly. To verify that we need fft2 I discarded one of the blobs, and then we know that a single Gaussian blob should transform into a Gaussian blob (with a certain phase, that's not shown when plotting absolute value). I also decreased the standard deviation so that the frequency response will widen a little.
Code:
import numpy as np
import matplotlib.pyplot as plt
x, y = np.meshgrid(np.linspace(-1,1,100), np.linspace(-1,1,100))
d = np.sqrt(x**2+y**2)
sigma, mu = .1, 0.0
g1 = np.exp(-( (d-mu)**2 / ( 2.0 * sigma**2 ) ) )
N = 300
positions = [ [150,100] ]#, [150,200] ]
sz2 = [int(x/2) for x in g1.shape]
F_2D = np.zeros([N,N])
for x0,y0 in positions:
F_2D[ x0-sz2[0]: x0+sz2[0], y0-sz2[1]:y0+sz2[1] ] = g1 + 1j*0.
result = np.fft.fftshift(np.fft.fft2(F_2D))
plt.subplot(211); plt.imshow(F_2D)
plt.subplot(212); plt.imshow(np.absolute(result))
plt.title('$\sigma$=.1')
plt.show()
Result:
To get back to the original problem, we need only change
positions = [ [150,100] , [150,200] ]
and sigma=.35 instead of sigma=.1.
You should use complex numpy variables (by using 1j) and use fft2. For example:
N = 16
x0 = np.random.randn(N,N,2)
x = x0[:,:,0] + 1j*x0[:,:,1]
X = np.fft.fft2(x)
Using fftn on x0 will do a 3D FFT, and using fft will do vector-wise 1D FFT.
I have an array which consists in a delta function (either 0 or 1). I use this function to generate a step function array by applying a forward-fill algorithm. This array is the one I need for a certain operation.
This plot displays the delta and step arrays:
However, I need to increase the resolution of this array to perform the operation. However, I cannot directly apply something like numpy.interp
which distorts the original functions.
Hence my question would be which is the efficient (and pythonic way) to increase the resolution in a step function?
This is an example script:
import matplotlib.pyplot as plt
import numpy as np
def forward_filling(arr):
idx=np.where(arr==0,0,np.arange(len(arr)))
idx=np.maximum.accumulate(idx)
return arr[idx]
fig, axis = plt.subplots(1, 1)
x_array = np.arange(0, 15)
y_delta = np.zeros(len(x_array))
y_delta[3], y_delta[7], y_delta[13] = 1, 2, 3
step_function = forward_filling(y_delta)
axis.plot(x_array, y_delta, label='delta function', marker='o')
axis.plot(x_array, step_function, label='step function')
x_high_resolution = np.linspace(0, 15, 30)
delta_interpolated = np.interp(x_high_resolution, x_array, y_delta)
step_interpolated = np.interp(x_high_resolution, x_array, step_function)
axis.plot(x_high_resolution, delta_interpolated, label='delta function high resolution', marker='o')
axis.plot(x_high_resolution, step_interpolated, label='step function high resolution')
axis.legend()
axis.set_xlabel('x')
axis.set_ylabel('y')
plt.show()
As I suppose you would like to maintain the y value in the neighbourhood of each given y value, you could "substitute" each y-value for, say, 3 of the same values using a List Comprehension:
step_function_hi_res = np.array([np.repeat(step,3) for step in step_function]).flatten()
and then make the changes in your x-values as you already did:
x_high_resolution = np.linspace(0, len(step_function),len(step_function)*3)