Ejemplo n.º 1
0
def fourier_intro(time, data, freq, Pxx, time_slice, out_file):
    """Time- and frequency presentation of sound.
    Corresponds to Fig. 9.1 in the book"""

    fig, axs = plt.subplots(1, 3)
    axs[0].plot(time, data, lw=0.5)
    axs[0].set_xlabel('Time (s)')
    axs[0].set_ylabel('Sound-pressure ()')
    axs[0].margins(x=0)

    axs[1].plot(time, data)
    axs[1].set_xlim(time_slice)
    axs[1].set_xlabel('Time (s)')
    axs[1].set_yticklabels([])

    axs[2].plot(freq, np.sqrt(Pxx))
    axs[2].set_xlim([0, 4000])
    axs[2].set_xlabel('Frequency (Hz)')
    axs[2].set_ylabel('|FFT| ()')
    axs[2].ticklabel_format(style='sci', scilimits=(0, 4))

    # Position the plots
    axs[0].set_position([0.125, 0.11, 0.2, 0.775])
    axs[1].set_position([0.35, 0.11, 0.2, 0.775])

    show_data(out_file)
Ejemplo n.º 2
0
def noise_effects(time, sound, Pxx, time_slice, duration, out_file):
    """Effect of adding noise to a signal on the powerspectrum
    Corresponds to Fig. 9.8 in the book
    """

    # Note that a1 has been normalized to have a range of 1
    sound_noisy = sound + 1 / 100 * np.random.randn(len(sound))
    fft_noisy = np.fft.fft(sound_noisy)
    Pxx_noisy = np.abs(fft_noisy)**2

    # Normalize to 'density'
    Pxx_noisy = Pxx_noisy * 2 / (np.sum(Pxx_noisy) / duration)

    fig, axs = plt.subplots(1, 2)
    axs[0].plot(time, sound, label='original')
    axs[0].plot(time, sound_noisy, label='noise added')
    axs[0].set_xlabel('Time (s)')
    axs[0].set_ylabel('Sound-pressure ()')
    axs[0].set_xlim(time_slice)
    axs[0].legend()

    axs[1].semilogy(freq, Pxx, label='original', lw=0.5)
    axs[1].semilogy(freq, Pxx_noisy, label='noise added', lw=0.5)
    axs[1].set_xlabel('Frequency (Hz)')
    axs[1].set_ylabel('Powerspectrum (P**2/Hz)')
    axs[1].set_xlim([1200, 1700])

    plt.tight_layout()

    show_data(out_file)
Ejemplo n.º 3
0
def main():
    # Generate dummy data
    x = np.array([-2.1, -1.3, -0.4, 1.9, 5.1, 6.2])

    # Define the two plots
    fig, axs = plt.subplots(1, 2, sharey=True)

    # Generate the left plot
    plot_histogram(axs[0], x)

    # Generate the right plot
    explain_KDE(axs[1], x)

    # Save and show
    show_data('KDEexplained.jpg')
Ejemplo n.º 4
0
def show3D() -> None:
    """ Generate 3D plots. """

    # imports specific to the plots in this example
    from matplotlib import cm  # colormaps

    # This module is required for 3D plots!
    from mpl_toolkits.mplot3d import Axes3D

    # Twice as wide as it is tall.
    fig = plt.figure(figsize=plt.figaspect(0.5))
    set_fonts(16)

    #---- First subplot
    # Generate the data
    X = np.arange(-5, 5, 0.1)
    Y = np.arange(-5, 5, 0.1)
    X, Y = np.meshgrid(X, Y)
    R = np.sqrt(X**2 + Y**2)
    Z = np.sin(R)

    # Note the definition of "projection", required for 3D  plots
    #plt.style.use('ggplot')

    ax = fig.add_subplot(1, 2, 1, projection='3d')
    surf = ax.plot_surface(X,
                           Y,
                           Z,
                           rstride=1,
                           cstride=1,
                           cmap=cm.GnBu,
                           linewidth=0,
                           antialiased=False)
    #surf = ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap=cm.viridis_r,
    #linewidth=0, antialiased=False)
    ax.set_zlim3d(-1.01, 1.01)

    fig.colorbar(surf, shrink=0.5, aspect=10)

    #---- Second subplot
    # Get some 3d test-data
    from mpl_toolkits.mplot3d.axes3d import get_test_data

    ax = fig.add_subplot(1, 2, 2, projection='3d')
    X, Y, Z = get_test_data(0.05)
    ax.plot_wireframe(X, Y, Z, rstride=10, cstride=10)

    show_data('3dGraph.jpg')
Ejemplo n.º 5
0
def bode_log(out_file):
    """Logarithmic presentation of transfer function """

    fig, axs = plt.subplots(2, 1, sharex=True)

    # Indicate the approximate gains
    axs[0].plot([0, 1 / tau], [0, 0], ls='dashed', lw=3, color='C1')
    axs[0].plot([1 / tau, 10 / tau], [0, -20], ls='dashed', lw=3, color='C1')
    axs[0].set_xlim(1e-2, 1)

    # Bode magnitude plot
    axs[0].semilogx(w, mag, color='C0')
    axs[0].plot(w[index], mag[index], 'ro')  # Indicate cut-off frequency

    # Bode phase plot
    axs[1].semilogx(w, phase)
    axs[1].plot(w[index], phase[index], 'ro')

    # Format the plots
    axs[0].set_ylabel('Gain [dB]')
    axs[0].grid(True, ls='dotted')
    axs[0].margins(x=0)
    axs[0].annotate(r'$\omega = \frac{1}{\tau}$',
                    xy=(w[index], mag[index]),
                    xycoords='data',
                    xytext=(-10, -50),
                    textcoords='offset points',
                    fontsize=16,
                    arrowprops=dict(arrowstyle="->", connectionstyle="arc3"))

    axs[1].set_xlabel('Frequency [Hz]')
    axs[1].set_ylabel('Phase [deg]')
    axs[1].set_yticks([0, -45, -90], minor=False)
    axs[1].margins(x=0)
    axs[1].grid(True, ls='dotted')
    axs[1].annotate(r'$\omega = \frac{1}{\tau}$',
                    xy=(w[index], phase[index]),
                    xycoords='data',
                    xytext=(-10, 30),
                    textcoords='offset points',
                    fontsize=16,
                    arrowprops=dict(arrowstyle="->", connectionstyle="arc3"))

    show_data(out_file)
Ejemplo n.º 6
0
def linear_and_log(freq, Pxx, out_file):
    """Comparison of linear and log representatino of powerspectrum
    Corresponds to Fig. 9.7 in the book.
    """

    fig, axs = plt.subplots(1, 2)
    upper_limit = 4000
    axs[0].plot(freq, Pxx)
    axs[0].set_xlim([0, upper_limit])
    axs[0].set_xlabel('Frequency (Hz)')
    axs[0].set_ylabel('Powerspectrum ()')
    axs[0].ticklabel_format(style='sci', scilimits=(0, 4))

    axs[1].semilogy(freq, Pxx, lw=0.5)
    axs[1].set_xlim([0, upper_limit])
    axs[1].set_xlabel('Frequency (Hz)')
    axs[1].set_ylabel('Powerspectrum (dB)')

    plt.tight_layout()

    show_data(out_file)
Ejemplo n.º 7
0
def bode_linear(out_file):
    """Linear presentation of transfer function """
    fig, axs = plt.subplots(2, 1, sharex=True)

    # Bode magnitude plot
    axs[0].plot(w, 10**(mag / 20))
    axs[0].plot(w[index], 10**(mag[index] / 20), 'ro')

    # Bode phase plot
    axs[1].plot(w, phase)
    axs[1].plot(w[index], phase[index], 'ro')

    # Format the plots
    axs[0].set_ylabel('Gain [linear]')
    axs[0].set_ylim([-0.10, 1.1])
    axs[0].margins(x=0)
    axs[0].grid(True, ls='dotted')
    axs[0].annotate(r'$\omega = \frac{1}{\tau}$',
                    xy=(w[index], 10**(mag[index] / 20)),
                    xycoords='data',
                    xytext=(10, 20),
                    textcoords='offset points',
                    fontsize=16,
                    arrowprops=dict(arrowstyle="->", connectionstyle="arc3"))

    axs[1].set_xlabel('Frequency [Hz]')
    axs[1].set_ylabel('Phase [deg]')
    axs[1].margins(x=0)
    axs[1].set_yticks([0, -45, -90], minor=False)
    axs[1].grid(True, ls='dotted')
    axs[1].annotate(r'$\omega = \frac{1}{\tau}$',
                    xy=(w[index], phase[index]),
                    xycoords='data',
                    xytext=(10, 30),
                    textcoords='offset points',
                    fontsize=16,
                    arrowprops=dict(arrowstyle="->", connectionstyle="arc3"))

    show_data(out_file)
Ejemplo n.º 8
0
def feedback(tau: float, fb_gain: float) -> None:
    """Simulation of a negative feedback system, using the package 'control'.
    'time', 'in_signal', 'num' and 'den' are taken from the global workspace
    
    Parameters
    ----------
    tau : time constant of a first order lag [sec]
    fb_gain : feedback gain
    """

    # First, define the feedforward transfer function
    sys = control.TransferFunction(num, den)
    print(sys)  # 1 / (tau*s + 1)

    # Simulate the response of the feedforward system
    t_ff, out_ff = control.forced_response(sys, T=time, U=in_signal)

    # Then define a feedback-loop, with gain fb_gain
    sys_total = control.feedback(sys, fb_gain)
    print(sys_total)  # 1 / (tau*s + (1+k))

    # Simulate the response of the feedback system
    t_fb, out_fb = control.forced_response(sys_total, T=time, U=in_signal)

    # Show the signals
    plt.plot(time, in_signal, '-', label='Input')
    plt.plot(t_ff, out_ff, '--', label='Feedforward')
    plt.plot(t_fb, out_fb, '-.', label='Feedback')

    # Format the plot
    plt.xlabel('Time [sec]')
    plt.title(f"First order lag (tau={tau} sec)")
    print('Simulated with "control"')
    plt.legend()

    out_file = 'feedback.jpg'
    show_data(out_file)
Ejemplo n.º 9
0
def welch_periodogram(data, rate, freq, Pxx, out_file):
    """Comparison of simple powerspectrum to Welch-periodogram
    Corresponds to Fig. 9.9 in the book.
    """

    fig, axs = plt.subplots(1, 2)
    f, welch = signal.welch(data, fs=rate, nperseg=len(data) / 8)
    df = np.diff(f)[0]
    # "normalize" welch
    welch = welch / (np.sum(welch) * df)

    axs[0].semilogy(freq, Pxx, label='Periodogram', lw=0.5)
    axs[0].semilogy(f, welch, label='Welch', lw=0.8)
    axs[0].set_xlim([0, rate / 2])
    axs[0].set_ylabel('Powerspectrum (P**2/Hz)')
    axs[0].set_xlabel('Frequency (Hz)')

    axs[1].semilogy(freq, Pxx, label='Pxx')
    axs[1].semilogy(f, welch, label='Welch')
    axs[1].set_xlim([800, 1100])
    axs[1].set_xlabel('Frequency (Hz)')
    axs[1].legend()

    show_data(out_file)
Ejemplo n.º 10
0
    # Add the text
    fs = 18
    plt.text(11, 5.5, '$\pm$ 1SD', fontsize=fs, 
             fontstyle='italic', color='C0')
    plt.text(62, 5.2, '$\pm$ 1SEM', fontsize=fs, 
             fontstyle='italic', color='C1')

    # plt.annotate('mean', (110,np.mean(x)),xycoords='data',
    #         fontsize=fs, xytext=(110, 5.5), textcoords='data',
    #         arrowprops={
    #             'facecolor':'black',
    #             'shrink':1,
    #             'headwidth':6,
    #             'headlength':6,
    #             'width': 1})

    plt.annotate('mean', (-5,np.mean(x)),xycoords='data',
            fontsize=fs, xytext=(-40, 4.5), textcoords='data',
            color = [0.6, 0.6, 0.6],
            arrowprops={
                'color':[0.6, 0.6, 0.6],
                'shrink':1,
                'headwidth':6,
                'headlength':6,
                'width': 1})

    # Save and show
    plt.tight_layout()
    outFile = 'standardError.jpg'
    show_data(outFile, out_dir='.')
Ejemplo n.º 11
0
# Import the required libraries
import numpy as np
import matplotlib.pyplot as plt
from skimage import data

from utilities.my_style import set_fonts, show_data

# Get a color-image
img = data.astronaut()
nrows, ncols = img.shape[:2]

# Make vectors from 1 to 0, with lengths matching the image
alpha_row = np.linspace(1, 0, ncols)
alpha_col = np.linspace(1, 0, nrows)

# Make coordinate-grids
X, Y = np.meshgrid(alpha_row, alpha_col)

# Scale the vector from 0 to 255, and
# let the image fade from top-right to bottom-left
X_Y = np.uint8(X * Y * 255)
X_Y = np.atleast_3d(X_Y)  #make sure the dimensions matches the image

# Add the alpha-layer
img_alpha = np.concatenate((img, X_Y), axis=2)

plt.imshow(img_alpha)

out_file = 'fading_astronout.png'
show_data(out_file)
Ejemplo n.º 12
0
    # Generate the base image
    data = np.zeros((99, 99))
    data[34:66, 33:67] = 1
    data[85:87, 85:87] = 1
    data[49:51, 49:51] = 0

    # Show the original image
    fig, ax = plt.subplots()
    plt.gray()
    ax.imshow(data)
    ax.set_title('Original Image')
    ax.get_xaxis().set_visible(False)
    ax.get_yaxis().set_visible(False)

    out_file = 'Square.jpg'
    show_data(out_file)

    # Perform the morphological operations
    selem = morphology.square(5)
    fig, axs = plt.subplots(2, 2, figsize=(8, 8))

    show_modImage(data, 'binary_erosion', axs[0][0], 'Eroded')
    show_modImage(data, 'binary_dilation', axs[0][1], 'Dilated')
    show_modImage(data, 'binary_opening', axs[1][0],
                  'Opened (Dilation after Erosion)')
    show_modImage(data, 'binary_closing', axs[1][1],
                  'Closed (Erosion after Dilation)')

    out_file = 'Square_Morphological.jpg'
    show_data(out_file, out_dir='.')
Ejemplo n.º 13
0
def simplePlots() -> None:
    """ Demonstrate the generation of different statistical standard plots. """

    # Univariate data -------------------------

    # Make sure that always the same random numbers are generated
    np.random.seed(1234)

    # Generate data that are normally distributed
    x = np.random.randn(500)

    # Other graphics settings
    # Set " context='poster' " for printouts, and "set_fonts(32)"
    sns.set(context='notebook', style='ticks', palette='muted')

    # Set the fonts the way I like them
    set_fonts(16)

    # Scatter plot
    plt.plot(x, '.', markersize=7)
    plt.xlim([0, len(x)])

    # Save and show the data, in a systematic format
    printout('scatterPlot.jpg',
             xlabel='Datapoints',
             ylabel='Values',
             title='Scatter')

    # Histogram
    plt.hist(x)
    printout('histogram_plain.jpg',
             xlabel='Data Values',
             ylabel='Frequency',
             title='Histogram, default settings')

    plt.hist(x, 25, density=True)
    printout('density_histogram.jpg',
             xlabel='Data Values',
             ylabel='Probability',
             title='Density Histogram, 25 bins')

    # Boxplot
    # The ox consists of the first, second (middle) and third quartile
    set_fonts(18)
    plt.boxplot(x, sym='*')
    printout('boxplot.jpg', xlabel='Values', title='Boxplot')

    plt.boxplot(x, sym='*', vert=False)
    plt.title('Boxplot, horizontal')
    plt.xlabel('Values')
    plt.show()

    # Errorbars
    x = np.arange(5)
    y = x**2
    errorBar = x / 2
    plt.errorbar(x, y, yerr=errorBar, fmt='o', capsize=5, capthick=3)
    plt.xlim([-0.2, 4.2])
    plt.ylim([-0.2, 19])
    printout('Errorbars.jpg',
             xlabel='Data Values',
             ylabel='Measurements',
             title='Errorbars')

    # SD for two groups
    weight = {'USA': 89, 'Austria': 74}
    weight_SD_male = 12
    plt.errorbar([1, 2],
                 weight.values(),
                 yerr=weight_SD_male * np.r_[1, 1],
                 capsize=5,
                 LineStyle='',
                 marker='o')
    plt.xlim([0.5, 2.5])
    plt.xticks([1, 2], weight.keys())
    plt.ylabel('Weight [kg]')
    plt.title('Adult male, mean +/- SD')

    show_data('SD_groups.jpg', out_dir='.')

    # Barplot
    # The font-size is set such that the legend does not overlap with the data
    np.random.seed(1234)
    set_fonts(16)

    df = pd.DataFrame(np.random.rand(7, 3), columns=['one', 'two', 'three'])
    df.plot(kind='bar', grid=False, color=sns.color_palette('muted'))

    show_data('barplot.jpg')

    # Bivariate Plots
    df2 = pd.DataFrame(np.random.rand(50, 3), columns=['a', 'b', 'c'])
    df2.plot(kind='scatter', x='a', y='b', s=df2['c'] * 500)
    plt.axhline(0, ls='--', color='#999999')
    plt.axvline(0, ls='--', color='#999999')
    printout('bivariate.jpg')

    sns.set_style('ticks')

    # Pieplot
    txtLabels = 'Cats', 'Dogs', 'Frogs', 'Others'
    fractions = [45, 30, 15, 10]
    offsets = (0, 0.05, 0, 0)

    plt.pie(fractions,
            explode=offsets,
            labels=txtLabels,
            autopct='%1.1f%%',
            shadow=True,
            startangle=90,
            colors=sns.color_palette('muted'))
    plt.axis('equal')
    printout('piePlot.jpg', title=' ')
Ejemplo n.º 14
0
# Formatting
set_fonts(14)

# Noisy sine
t = np.arange(0, 20, 0.05)
x = np.sin(t)
x_noisy = x + 0.06 * t + 0.3 * np.random.randn(len(x))

#plt.plot(t, x)
#show_data('sine.jpg')

fig, axs = plt.subplots(1, 2)
axs[0].plot(t, x_noisy)
axs[1].plot(t, x)

show_data('noisy_sine.svg')

# BW-Image
img_file = '../../data/HagenbergRocks.jpg'
img = color.rgb2gray(plt.imread(img_file))

# Edges
edges = feature.canny(img, sigma=2.5)

fig, ax = plt.subplots(1, 1)
#axs[0].imshow(img, cmap='gray')
#axs[0].axis('off')

ax.imshow(edges, cmap='gray')
ax.axis('off')
Ejemplo n.º 15
0
    fs = 18
    plt.text(11, 5.5, '$\pm$ 1SD', fontsize=fs)
    plt.text(62, 5.2, '$\pm$ 1SEM', fontsize=fs)

    # plt.annotate('mean', (110,np.mean(x)),xycoords='data',
    #         fontsize=fs, xytext=(110, 5.5), textcoords='data',
    #         arrowprops={
    #             'facecolor':'black',
    #             'shrink':1,
    #             'headwidth':6,
    #             'headlength':6,
    #             'width': 1})

    plt.annotate('mean', (-5, np.mean(x)),
                 xycoords='data',
                 fontsize=fs,
                 xytext=(-40, 4.5),
                 textcoords='data',
                 color=[0.6, 0.6, 0.6],
                 arrowprops={
                     'color': [0.6, 0.6, 0.6],
                     'shrink': 1,
                     'headwidth': 6,
                     'headlength': 6,
                     'width': 1
                 })

    # Save and show
    outFile = ('standardError.jpg')
    show_data(outFile)
Ejemplo n.º 16
0
def power_spectrum(t: np.ndarray, dt: float, sig: np.ndarray,
                   sig_ideal: np.ndarray) -> None:
    """ Demonstrate three different ways to calculate the power-spectrum
    
    Parameters
    ----------
    t : time [sec]
    dt : sample period [sec]
    sig : sample signal to be analyzed
    sig_ideal : signal without noise
    """
    
    set_fonts(16)
    
    fig, axs = plt.subplots(1,2, figsize=(10, 5))
    
    if latex_installed:
        txt ='$\displaystyle signal=offset + \sum_{i=0}^{2} a_i*sin(\omega_i*t) + noise$'
        label = '$|FFT|\; ()$'
        label2 = '$|FFT|^2  ()$'
    else:
        txt = 'signal = offset + sum(i=0:2) a_i*sin(omega_i*t)'
        label = '|FFT| ()'
        label2 = '|FFT|^2 ()'
        
    # From a quick look we learn - nothing
    axs[0].plot(t, sig, lw=0.7, label='noisy')
    axs[0].plot(t, sig_ideal, ls='dashed', lw=2, label='ideal')
    axs[0].set_xlim(0, 0.4)
    axs[0].set_ylim(-15, 25)
    axs[0].set_xlabel('Time (s)')
    axs[0].set_ylabel('Signal ()')
    axs[0].legend()
    axs[0].text(0.2, 24, s=txt, fontsize=16)
    
    # Calculate the spectrum by hand
    fft = np.fft.fft(sig)
    print(fft[:3])
    fft_abs = np.abs(fft)
    
    # The easiest way to calculate the frequencies
    freq = np.fft.fftfreq(len(sig), dt)
    
    axs[1].plot(freq, fft_abs)
    axs[1].set_xlim(0, 35)
    axs[1].set_xlabel('Frequency (Hz)')
    axs[1].set_ylabel(label)
        
    axs[1].set_yticklabels([])
    show_data('FFT_sines.jpg')
    
    # Also show the double-sided spectrum
    fig, ax = plt.subplots(1,1)
    ax.plot(fft_abs)
    #ax.set_xlim(0, 35)
    ax.set_xlabel('Points')
    ax.set_ylabel(label)
    plt.tight_layout()
    show_data('FFT_doublesided.jpg')
    
    # With real input, the power spectrum is symmetrical and we only one half
    fft_abs = fft_abs[:int(len(fft_abs)/2)]
    freq = freq[:int(len(freq)/2)]
    
    # The power is the norm of the amplitude squared
    Pxx = fft_abs**2
    # Showing the same data on a linear and a log scale
    fig, axs = plt.subplots(2,1, sharex=True)
    axs[0].plot(freq, Pxx)
    axs[0].set_ylabel('Power (linear)')
    axs[1].semilogy(freq, Pxx)
    axs[1].set_xlabel('Frequency (Hz)')
    axs[1].set_ylabel('Power (dB)')
    show_data('FFT_sines_power_lin_log.jpg')
    
    # Periodogram and Welch-Periodogram
    f_pgram, P_pgram = signal.periodogram(sig, fs = 1/dt)
    f_welch, P_welch = signal.welch(sig, fs = 100, nperseg=2**8)
    
    fig, axs = plt.subplots(2, 1, sharex=True)
    
    axs[0].semilogy(f_pgram, P_pgram, label='periodogram')
    axs[1].semilogy(f_welch, P_welch, label='welch')
    
    axs[0].set_ylabel('Spectral Density (dB)')
    axs[0].legend()
    axs[0].set_ylim(1e-4, 1e3)
    axs[1].set_xlabel('Frequency (Hz)')
    axs[1].set_ylabel('Spectral Density (dB)')
    axs[1].legend()
    show_data('FFT_sines_periodogram.jpg')
Ejemplo n.º 17
0
if __name__ == '__main__':

    # Generate the data
    signal = np.zeros(20)
    signal[7:10] = 1
    signal[14:17] = 1

    feature = np.zeros(7)
    feature[2:5] = 1

    # Plot the auto-correlation
    set_fonts(14)
    fig, axs = plt.subplots(2, 1)
    axs[0].plot(signal, 'o-')
    axs[0].hlines(0, -0.5, 20, ls='dotted')
    axs[0].set_xticks(np.arange(0, 21, 2))
    axs[0].set_xlim(-0.5, 20)
    axs[0].set_ylabel('Signal')
    axs[0].set_yticks([0, 0.5, 1])

    axs[1].plot(feature, 'o-')
    axs[1].hlines(0, -0.5, 20, ls='dotted')
    axs[1].set_xticks(np.arange(0, 20, 2))
    axs[1].set_xticks(np.arange(0, 21, 2))
    axs[1].set_xlim(-0.5, 20)
    axs[1].set_xlabel('Shift')
    axs[1].set_ylabel('Feature')
    axs[1].set_yticks([0, 0.5, 1])
    sig_file = 'CorrDemo.jpg'
    show_data(sig_file, out_dir='.')