Home > Enterprise >  Adjust xrange depending on where signal is
Adjust xrange depending on where signal is

Time:11-24

Suppose I have a stream of data, make it a Bell curve for simplicity, acquired from a large range:

import numpy as np
import matplotlib.pyplot as plt


def pdf(x, mean, std):
    """Return a PDF."""
    y_out = 1/(std * np.sqrt(2 * np.pi)) * np.exp(-(x - mean)**2 / (2 * std**2))
    return y_out


x = np.linspace(-1000, 1000, 20000)
y = 100 * pdf(x, 0, 1)   np.random.normal(0, 1, 20000)

fig, ax = plt.subplots()
ax.plot(x, y)

The plot will show just a very narrow line because the x range is too big, and we do not need to have all the noise in the plot anyway.

In this case, it might make sense to plot this by only showing the range [-20, 20] for example: ax.set_xlim([-20, 20]). However, suppose now we have something like this from another acquisition:

y = 100 * pdf(x, -50, 1)   100 * pdf(x, 0, 1)   100 * pdf(x, 40, 1)   np.random.normal(0, 1, 20000)

With such a function, we will probably want to plot a wider range, e.g. ax.set_xlim([-70, 60]), to visualise all the signals acquired.

Is there a way to programmatically adjust the limits depending on the actual signal (i.e. anything above a certain threshold, say 10), without having to plot the whole range first, then adjusting it manually?

CodePudding user response:

Use enter image description here

CodePudding user response:

Very similar answer to Stef, except that I was proposing a minimum width and a percentage extra so the margin will depend on the amount of x you want to show, rather than a margin, so you can tweak window_excess and min_width. Something like this could be useful if you have lots of plots to make. Replacing Stef's get_lims function with this would achieve the result:

def get_lims(y, threshold = 10, window_excess = 0.5, min_width = 100):
    minwidth = min_width / (1   window_excess)

    a = np.argwhere(y > threshold)
    
    da = max(minwidth, x[a[-1]] - x[a[0]])
    ma = (x[a[-1]]   x[a[0]]) / 2
    minx = ma - da * (1   window_excess) / 2
    maxx = ma   da * (1   window_excess) / 2
    return([minx, maxx])

enter image description here

You'd just need to add a check that xmin and xmax are within the range of x.

  • Related