1

for a particular purpose, I want to plot 2-3 different figures using matplotlib and add different graphs to each of these figures. My particular requirement is complex and hard to explain, so I will try to explain with a simpler example.

For example, imagine I have a list of signals called [signal_1,signal_2,signal_3, .... , signal _40] where each 'signal_XXX' represents a numpy-array, some of length 5000 and other length 10,000.

I want to plot all these signals in 2 different graphs, depending on their length.

import matplotlib.pyplot as plt
my_signals = [ signal_1,signal_2,....,signal_40]

fig_5000 = plt.figure(1)

fig_10000 = plt.figure(2)

for signal_i in my_signals :
    if len(signal_i) == 5000 :
        fig_5000.plot(signal_i)
    if len(signal_i) == 10000 :
        fig_10000.plot(signal_i)

# now I want to individually show these 2 figures
fig_5000.show()
" do something else here "
fig_10000.show()

Obviously the code which I wrote will not work, also on the last part if I use plt.show() both graphs will show at the same time, which I don't want.

Is there any way to do the stuff which I want to do using matplotlib ? or should I try something else?

EDIT

I include a 'working' code , with suggestion from Diziet Asahi,

import numpy
import matplotlib.pyplot as plt
my_signals = []
for i in range (0,25):
    if i//2 == 0 :
        my_signals.append( numpy.random.rand(100))
    if i//2 == 1 :
        my_signals.append( numpy.random.rand(200))
"""numpy.random.rand craetes an array with random numbers of the given shape.
now we have  a list of 50 arrays with 100 and 200 lengths """

fig_100 = plt.figure(1)
ax100 = fig_100.add_subplot(111)
plt.title(" length = 100")
fig_200 = plt.figure(2)
plt.title(" length = 200")
ax200 = fig_200.add_subplot(111)


for arrayzz in my_signals :
    if len(arrayzz) == 100 :
        ax100.plot(arrayzz)
    if len(arrayzz) == 200:
        ax200.plot(arrayzz)

plt.show()

This fixes the first part of the earlier problem. Still, I can't show them individually.

brownser
  • 545
  • 7
  • 25
  • 1
    Would you mind correcting the grammar, spelling,capitalization in your question and its title? – wwii Nov 20 '19 at 15:49
  • 3
    `"Obviously the code which I wrote will not work'` - you should explain why it doesn't work so *we* don't have to run it and find out for *ourselves*. – wwii Nov 20 '19 at 15:51
  • 2
    Can you make a Minimal Reproducible Example (https://stackoverflow.com/help/minimal-reproducible-example) i.e. make the code you post actually work. – Tom Myddeltyn Nov 20 '19 at 15:51
  • Because the ` 'Figure' object has no attribute 'plot'`, so we can't specify to which figure the plot should go by the way I attempted. – brownser Nov 20 '19 at 15:53
  • [Multiple Figs Demo](https://matplotlib.org/3.1.1/gallery/subplots_axes_and_figures/multiple_figs_demo.html) ... [Working with multiple figures and axes-tutorial](https://matplotlib.org/3.1.1/tutorials/introductory/pyplot.html#working-with-multiple-figures-and-axes) – wwii Nov 20 '19 at 15:56
  • Possible duplicate of [Plotting on multiple figures with subplots in a single loop](https://stackoverflow.com/questions/46573570/plotting-on-multiple-figures-with-subplots-in-a-single-loop) – wwii Nov 20 '19 at 16:01
  • That question doesn't answer my second question, that is to show the 2 graphs individually.@wwii – brownser Nov 20 '19 at 16:34

2 Answers2

4

In addition to creating figures you also need to create axes. You don't say if you want all your signals to be on the same axes, but generally this should do the trick:

import matplotlib.pyplot as plt
my_signals = [ signal_1,signal_2,....,signal_40]

fig_5000 = plt.figure(1)
ax_5000 = fig_5000.add_subplot(111)

fig_10000 = plt.figure(2)
ax_10000 = fig_10000.add_subplot(111)

for signal_i in my_signals :
    if len(signal_i) == 5000 :
        ax_5000.plot(signal_i)
    if len(signal_i) == 10000 :
        ax_10000.plot(signal_i)

plt.show()
Diziet Asahi
  • 38,379
  • 7
  • 60
  • 75
  • Hi, Thanks your answer fixed the first part of my question. Can you also tell me how to display both these figures one-by-one ? `plt.show()` will plot both the figures at the same time... – brownser Nov 20 '19 at 16:21
  • For anyone who gets confused by seeing `subplot` being used, let me inform you that the figures get plotted in two separate windows. – Nav Aug 03 '20 at 11:14
1

There is no good solution for this currently. plt.show() shows all open pyplot figures. You can of course close anyThe problem is essentially the same as this one, and of course writing your own GUI for the figure, showing it whenever you want is possible, but cumbersome.

There is an idea to enhance the show function in a future version, see https://github.com/matplotlib/matplotlib/pull/14024, but for now the solution would be

import numpy
import matplotlib.pyplot as plt

def reshow(fig):
    import importlib
    import matplotlib.backends
    import matplotlib.backend_bases
    backend_mod = importlib.import_module(f"matplotlib.backends.backend_{plt.get_backend().lower()}")
    Backend = type("Backend", (matplotlib.backends._Backend,), vars(backend_mod))
    fm = Backend.new_figure_manager_given_figure(1, fig)
    matplotlib.backend_bases.Gcf.set_active(fm)
    plt.show()


my_signals = []
for i in range (0,25):
    if i//2 == 0 :
        my_signals.append( numpy.random.rand(100))
    if i//2 == 1 :
        my_signals.append( numpy.random.rand(200))


fig_100 = plt.figure(1)
ax100 = fig_100.add_subplot(111)
ax100.set_title(" length = 100")

fig_200 = plt.figure(2)
ax200 = fig_200.add_subplot(111)
ax200.set_title(" length = 200")

for arrayzz in my_signals :
    if len(arrayzz) == 100 :
        ax100.plot(arrayzz)
    if len(arrayzz) == 200:
        ax200.plot(arrayzz)

# First close all figures
plt.close("all")
#Then (re)show a single figure
reshow(fig_100)
# and the other one
reshow(fig_200)
ImportanceOfBeingErnest
  • 321,279
  • 53
  • 665
  • 712