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()

2 Answers 2

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

Sign up to request clarification or add additional context in comments.

3 Comments

How would I add a single legend at the bottom of the whole figure?
For adding a legend, I would like to refer you to this answer, since this is probably out of the scope of this question here.
For those using Python 3, you need to change xrange into range.
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.

1 Comment

it'd be more pythonic/idiomatic + future/backwards compatible to use for num, c in enumerate(countries, 1):

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.