How to update matplotlib's imshow() window interactively?

后端 未结 4 1532
孤独总比滥情好
孤独总比滥情好 2020-11-30 05:19

I\'m working on some computer vision algorithm and I\'d like to show how a numpy array changes in each step.

What works now is that if I have a simple imshow(

4条回答
  •  旧巷少年郎
    2020-11-30 06:07

    I struggled to make it work because many post talk about this problem, but no one seems to care about providing a working example. In this case however, the reasons were different :

    • I couln't use Tiago's or Bily's answers because they are not in the same paradigm as the question. In the question, the refresh is scheduled by the algorithm itself, while with funcanimation or videofig, we are in an event driven paradigm. Event drivent programming is unavoidable for modern user interface programming, but when you start from a complex algorithm, it might be difficult to convert it to an event driven scheme - and I wanted to be able to do it in the classic procedural paradigm too.
    • Bub Espinja replied suffered another problem : I didn't try it in the context of jupyter notebooks, but repeating imshow is wrong since it recreates new data structures each time which causes an important memory leak and slows down the whole display process.

    Also Tiago mentioned calling draw(), but without specifying where to get it from - and by the way, you don't need it. the function you really need to call is flush_event(). sometime it works without, but it's because it has been triggered from somewhere else. You can't count on it. The real important point is that you cannot call imshow() on an empty table, or it will fail to initialize it's color map and set_data will fail too.

    Here is a working solution :

    IMAGE_SIZE = 500
    import numpy as np
    import matplotlib.pyplot as plt
    
    
    plt.ion()
    
    fig1, ax1 = plt.subplots()
    fig2, ax2 = plt.subplots()
    
    # this example doesn't work because array only contains zeroes
    array = np.zeros(shape=(IMAGE_SIZE, IMAGE_SIZE), dtype=np.uint8)
    axim1 = ax1.imshow(array)
    
    array[0, 0] = 99 # this value allow imshow to initialise it's color scale
    axim2 = ax2.imshow(array)
    
    del array
    
    for _ in range(50):
        print(".", end="")
        matrix = np.random.randint(0, 100, size=(IMAGE_SIZE, IMAGE_SIZE), dtype=np.uint8)
        
        axim1.set_data(matrix)
        fig1.canvas.flush_events()
        
        axim2.set_data(matrix)
        fig1.canvas.flush_events()
    print()
    

提交回复
热议问题