Pan view functionality

Issue #180 resolved
Denis Hayrullin created an issue

Hello, I like your program very much. It is rather simple also in learn and is effective in work.

However very much there is no possibility of more exact navigation in a visualizer window. Especially it concerns panning of a view.

I suggest to add possibility of panning by means of dragging by a mouse in a visualizer window with some pressed button, for example, the middle button of a mouse.

I made corresponding changes to the program and tested in work (image below). Panning works rather well, it is possible to move a view with an accuracy of pixels, but there are problems with a performance during the work with complex projects. I think these problems are related to 'matplotlib' library.

Whether there is a sense to add this function even taking into account low performance? Or any ideas as it is possible to increase visualizer performance?

flat_pan2.gif

Comments (10)

  1. Juan Pablo Caram repo owner

    Hi Denis,

    I think we can put this in regardless of the performance for now. Unless it's extremely bad, then perhaps we should go straight into a better solution so that we don't scare the users.

    It would be great if you could work on a higher performance approach, but for now you can submit a pull request for what you have.

    To improve the performance we need to cache the mouse motion. Something like this:

    def on_mouse_move(x, y):
       if cache_active:
          clear_cache()
       cache(x, y)
    
    def cache(x, y):
       timer(0.2, lambda: pan(x,y))
    

    The above pseudo-code is very simplistic. If you keep moving the mouse it will never update the screen until you stop. So instead the cache can be a list of timers perhaps, and only when the list is full you start deleting the last (newest) one such that the older ones are allowed to complete. Or update at a fixed rate:

    def on_mouse_move(x, y):
       t = 0.2
       if cache_active:
          t = remaining_time()
       cache(x, y, t)
    
    def cache(x, y, t):
       timer(t, lambda: pan(x,y))
    

    Something like that. The timers would have to be PyQt timers I believe.

  2. Denis Hayrullin reporter

    Hello.

    After superficial studying, and profiling of the program, it is possible to draw a conclusion: the matplotlib library is obviously not intended for such graphics.

    There are some bottlenecks:

    1) Each new object in project ("axes" it matplolib term), even it's empty, will slow down work of a visualizer via this code:

    # backend_bases_py
    
            # Find all axes containing the mouse
            if self.canvas.mouse_grabber is None:
                axes_list = [a for a in self.canvas.figure.get_axes() 
                            if a.in_axes(self)]
            else:
                axes_list = [self.canvas.mouse_grabber]
    

    "in_axes()" - function slow one, very very slow.

    2) Rasterizer. Can't fill so many polygons quickly enough. It can only work good with lines, and it's about 1 klines.

    Perhaps, we need to use GPU? OpenGL as cross-platform solution.

  3. Juan Pablo Caram repo owner

    There are two separate issues here:

    1. Matplotlib has performance limitations which affect the program as the complexity of the graphics grow. This affects the overall plot time and therefore any zoom/pan.

    2. When panning with the mouse, the number of times the "mouse_move" event handler is called is too, and unnecessarily, large. This is what I was trying to explain in my last comment. I believe this can be a problem even if we have a good solution for problem 1.

    Let's address problem 2 in this issue. I've created #181 for problem 1.

  4. Denis Hayrullin reporter

    "mouse_move" event can be called about 500+ times per second.

    "draw_idle()" function filters all excess calls during drawing.

    So, during pan view we have greatest possible FPS-value caused by drawing procedure.

    If we have to much FPS, we can limit it by timers/flags, set constant visualizer update time and so on. But now we have even no necessary minimum.

    Pass to #181.

  5. Roberto Lo Giacco

    Yes guys, I'm only a user and not a contributor, but panning is really painful in it's current implementation: right or middle mouse buttons are definitely the way to go!

    I've created a very complex work by doing panelization of 10 small boards and the whole project just froze up... In any case, while it can be acceptable for some slowness on big projects (it's a completely free tool damn it!) the current panning gestures are painful.

  6. Juan Pablo Caram repo owner

    Roberto, the panning with the middle mouse button is currently working.

    Unfortunately the performance improvement is a big project. See #181. I haven't heard from Denis who was sharing the load with me, and I'm buried in work right now. Maybe he'll see this thread's activity and come back!

  7. Log in to comment