How to put multiple matshow() results in one figure?

Viewed 7208

I'm trying to make a figure like this. A matrix of plots, each is a visualization of a numerical matrix.

enter image description here

I thought code should look something like the following:

using PyPlot

figure()
for i in 1:100
    subplot(10, 10, i)
    matshow(rand(10, 10))
end

But the plots would pop out in new windows independently, instead of in separate parts of the same figure. What did I do wrong?

Thanks in advance for your time!

2 Answers

Disclaimer: I've absolutely no experience with Julia. So there may be some caveats about the following I'm not aware of.

From the matshow documentation:

matplotlib.pyplot.matshow(A, fignum=None, **kw)
Display an array as a matrix in a new figure window. [...]
fignum: [ None | integer | False ]
By default, matshow() creates a new figure window with automatic numbering. If fignum is given as an integer, the created figure will use this figure number. Because of how matshow() tries to set the figure aspect ratio to be the one of the array, if you provide the number of an already existing figure, strange things may happen. If fignum is False or 0, a new figure window will NOT be created.

Two possible options might thus be:

  • Use fignum=false

    figure()
    for i in 1:100
        subplot(10, 10, i)
        matshow(rand(10, 10), fignum=false)
    end
    
  • Use imshow instead of matshow (because imshow does not create a new figure by default)

    figure()
    for i in 1:100
        subplot(10, 10, i)
        imshow(rand(10, 10))
    end
    

My preferred way using pyplot is avoid using the "magic" that guesses which subplot you want to use. Thus I would usually do something like this:

figure()
for i in 1:100
    ax = subplot(10, 10, i) # assign ax to that subplot
    ax[:matshow](rand(10, 10)) # call plot method on that specific subplot
end

or for even more flexibility you can do:

f,axs=subplots(10,10)            # create all the subplots at the start
for ax in axs                    # instead use `for (i,ax) enumerate(axs)` if you need the index)
    ax[:matshow](rand(10,10))    # plot on each iteration
end
Related