Setting pglive live plotting axis range based on time-span: Understanding 'roll_on_tick' parameter

84 Views Asked by At

I'm currently working on a Python GUI aimed at live-plotting (linear plots) real-time acquired data for tracking photon intensity over time. For this purpose, I'm using PyQt5 and pglive. The application supports multi-channel live-plotting (from 1 to 8 simultaneously active channels, meaning if I have 8 active channels, I'll see the corresponding 8 live plots in the interface). Each plot exhibits the following characteristics:

  • Y Axis: Refers to photon counts for a specific temporal acquisition point.

  • X Axis: Refers to the time value of acquisition (tick format follows pglive settings: Axis.TICK_FORMAT: Axis.DURATION, Axis.DURATION_FORMAT: Axis.DF_SHORT). Furthermore, the GUI is parameterized, allowing users to set:

  • Update rate or draw frequency (Hz) of the graph. Depending on the chosen setting (LOW or HIGH update rate) and the number of active channels, there's an algorithm that calculates the ideal frequency (ranging from 5Hz to 100Hz) behind the scenes.

  • Bin width (µs): This represents the temporal step of accumulated counts between one point/value on the graph and another. It denotes the time step in microseconds between photon counts points/values (range adjustable from 1µs to 1,000,000µs).

  • Time-span (s): It indicates the time value in seconds of the graphical time window that I want to visualize before the graph regenerates with the next time span's data. For instance, setting a time-span of 5 seconds, I'll see the last 5 seconds of acquired data each time. Initially 0s-5s, then 5s-10s, and so forth. This parameter accepts values from 1 second to 5 minutes. The max points, or the maximum number of total visible points on the graphs, are calculated behind the scenes by an algorithm considering bin width, time span, and update rate, ensuring a value that avoids overcrowding the graph.

Now, I'm trying to figure out how to manipulate pglive parameters to set the X-axis range based on the set time-span. Analyzing the library documentation and the specific source code file discussing this functionality at: https://github.com/domarm-comat/pglive/blob/main/pglive/examples_pyqt5/live_plot_range.py, it appears that the parameter to set is roll_on_tick. The issue lies in my inability to understand what influences this parameter and how to correctly set it based on the available information (update rate, time span, and bin width). Perhaps this is also due to it being my first foray into live plotting. I've attempted various algorithms to calculate this 'roll_on_tick', but I consistently get inconsistent results.

My goal is as follows:

To visualize the set time-span on the graph, regardless of the update rate, max-points, and bin-width. If I set a time-span of 5 seconds, I want the graph to scroll/regenerate every 5 seconds (thus, on the X-axis, I should see, for instance, the range first 0s - 5s, then 5s - 10s, and so on) consistently.

To achieve this, I need to comprehend what the 'roll_on_tick' parameter truly represents and its correlation with the data at my disposal. Can anyone provide guidance regarding this issue?

Thank you very much.

1

There are 1 best solutions below

0
Domarm On

Purpose of roll_on_tick attribute is to optimize plotting performance. Instead of replotting whole plot when adding new point, it do so only when number of points in the buffer reaches roll_on_tick value.

That said, you can say that 1 tick = 1 point on the axis.

For example if you set roll_on_tick = 50, and you will add new point at 10Hz frequency, you will roll your plot every 5 seconds.

Here is example output:

enter image description here

Pglive will first calculate difference between two points and multiple it by roll_on_tick value. In our example diff between two points is just 1, so it's 1 * 50 = 50. Then it will always render ahead of last roll_on_tick value. In our example it will be at point [50, 100, 150, ...].

This feature only works with equally separated values. It tries to render ahead apropriate amount of space and then fill the space with new points as they come.

Also pglive offers two ways of adding new point (1 tick). One is data_connector.cb_append_data_point and the other is data_connector.cb_append_data_array. For cb_append_data_array each point in the array is counted as 1 tick. That said, if you update your plot with array of 50 points and roll_on_tick = 50, plot will roll on every value update. You should also be aware of adding more points at once than roll_on_tick value. Otherwise update will be ahead of what is displayed.

I think the problem is if you are dynamically changing spacing between two displayed points. I can try to help you more if you provide me with some reproducible example.

There is also possibility of bug as well. So if you are sure, everything is correct on your don't hesitate to create new bug with some short, reproducible example and I will try to fix it.

Disclaimer: I'm owner of pglive repo.