7

I am trying to write a loop that will make a figure with 25 subplots, 1 for each country. My code makes a figure with 25 subplots, but the plots are empty. What can I change to make the data appear in the graphs?

fig = plt.figure()

for c,num in zip(countries, xrange(1,26)):
    df0=df[df['Country']==c]
    ax = fig.add_subplot(5,5,num)
    ax.plot(x=df0['Date'], y=df0[['y1','y2','y3','y4']], title=c)

fig.show()
LauraF
  • 345
  • 2
  • 5
  • 11

2 Answers2

14

You got confused between the matplotlib plotting function and the pandas plotting wrapper.
The problem you have is that ax.plot does not have any x or y argument.

Use ax.plot

In that case, call it like ax.plot(df0['Date'], df0[['y1','y2']]), without x, y and title. Possibly set the title separately. Example:

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

countries = np.random.choice(list("ABCDE"),size=25)
df = pd.DataFrame({"Date" : range(200),
                    'Country' : np.repeat(countries,8),
                    'y1' : np.random.rand(200),
                    'y2' : np.random.rand(200)})

fig = plt.figure()

for c,num in zip(countries, xrange(1,26)):
    df0=df[df['Country']==c]
    ax = fig.add_subplot(5,5,num)
    ax.plot(df0['Date'], df0[['y1','y2']])
    ax.set_title(c)

plt.tight_layout()
plt.show()

enter image description here

Use the pandas plotting wrapper

In this case plot your data via df0.plot(x="Date",y =['y1','y2']).

Example:

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

countries = np.random.choice(list("ABCDE"),size=25)
df = pd.DataFrame({"Date" : range(200),
                    'Country' : np.repeat(countries,8),
                    'y1' : np.random.rand(200),
                    'y2' : np.random.rand(200)})

fig = plt.figure()

for c,num in zip(countries, xrange(1,26)):
    df0=df[df['Country']==c]
    ax = fig.add_subplot(5,5,num)
    df0.plot(x="Date",y =['y1','y2'], title=c, ax=ax, legend=False)

plt.tight_layout()
plt.show()

enter image description here

ImportanceOfBeingErnest
  • 321,279
  • 53
  • 665
  • 712
6

I don't remember that well how to use original subplot system but you seem to be rewriting the plot. In any case you should take a look at gridspec. Check the following example:

import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec

fig = plt.figure()

gs1 = gridspec.GridSpec(5, 5)
countries = ["Country " + str(i) for i in range(1, 26)]
axs = []
for c, num in zip(countries, range(1,26)):
    axs.append(fig.add_subplot(gs1[num - 1]))
    axs[-1].plot([1, 2, 3], [1, 2, 3])

plt.show()

Which results in this:

matplotlib gridspec example

Just replace the example with your data and it should work fine.

NOTE: I've noticed you are using xrange. I've used range because my version of Python is 3.x. Adapt to your version.

armatita
  • 12,825
  • 8
  • 48
  • 49
  • 1
    it'd be more pythonic/idiomatic + future/backwards compatible to use `for num, c in enumerate(countries, 1):` – Paul H Oct 12 '17 at 16:59