[Python] resetting data limits on zoom in Matplotlib python program (long)

Discussão em 'Python' iniciado por Stack, Agosto 20, 2025.

  1. Stack

    Stack Membro Participativo

    I've created a program to display very high sample rate data in profile. There are 6 channels (mag[0..2] & diff[0..2]) sampled at 30 kHz. I display them in 3 profiles, mag[0] with diff[0], etc. All plots share the same x axis (nptime), which is numpy timedate64, with different scales for the mag and diff. Axes 0 to 2 represent the mag profiles and 3 to 5 are diff.

    In order to speed up the display I slice the data to the window limits and a desampling rate of 1, 10 or 100, based on the x extents. I do this in a callback on the xlim_changed event for axis 0.

    It almost works. I call set_ylim within the callback using the data range for the windowed data. For the mag channels the y limits are set correctly for 2 of the 3 panels, but the panel I zoomed on (whichever that is) ends up displaying the zoom extents not the new extents. For the diff channels I've set up axes 3 to 5 to sharey, so I only need to set axis 3, but the set_ylim is ignored. It ALWAYS displays with the y extent from the zoom. I actually don't want the ylim for diff to change at all, I always set it to the same value.

    def reset_data(self, ax):
    # the viewLim extents are decimal days, so some coordinate conversion is required
    width = ax.viewLim.width*86400
    start=np.datetime64(pd.to_datetime(self.nptime[0]).date()) +np.timedelta64(int(ax.viewLim.min[0]%1*8.64e10),'us')
    idx0 = self.find_nearest(self.nptime, start)
    end=np.datetime64(pd.to_datetime(self.nptime[0]).date()) +np.timedelta64(int(ax.viewLim.max[0]%1*8.64e10),'us')
    idx1 = self.find_nearest(self.nptime[idx0:], end) + idx0

    # the get_rate function returns 1 of 3 desample factors 1, 10 or 100
    rate = self.get_rate(width)

    xdata = self.nptime[idx0:idx1:rate]
    for i in range(3):
    ydata = self.mag[i, idx0:idx1:rate]
    ymin = ydata.min()
    ymax = ydata.max()
    diff = (ymax - ymin)*.1

    # self.lines is an array of the plots returned by self.ax[].plot()
    self.lines[0].set_data(xdata,ydata)
    self.ax.set_ylim(ymin-diff, ymax+diff)
    for i in range(3):
    ydata = self.diff[i, idx0:idx1:rate]
    self.lines[i+3][0].set_data(xdata,ydata)
    self.ax[3].set_ylim(self.min_diff, self.max_diff)


    before zoom: [​IMG]

    after zoom: [​IMG]

    Note that the panel limits for the mag (blue) channels have been set to the data limit (+10%) for panels 2&3, but the extents of the zoom box on panel 1. Also the pink trace is 7.5 to 27 on all 3 panels, which represents the zoom extents, not the limits I set.

    Sorry for the long post. I can't explain it any more briefly.

    Continue reading...

Compartilhe esta Página