1

I have a dataframe that looks like this:

runtime        name   grade   
2021-05-28     Jimmy  50.34  
2021-05-28      John  51.02
2021-05-28    Sherry  51.28
2021-05-28    Angela  45.99
2021-05-28      Mary  48.64
...
2021-08-23    Nathan  46.65
2021-08-23    Angela  50.64
2021-08-23    Sherry  46.77
2021-08-23      John  48.55
2021-08-23    Albert  48.89

I would like to create a subplot with df['grade'] for each unique df['name'] and a shared x-axis: runtime

This is what I have so far.

n = len(pd.unique(dfp['name']))

fig, axs = plt.subplots(nrows=n, figsize=(7, 5), sharex=True)
for ax, column, label in zip(axs,['grade'],['name']):
    dfp.plot(x='runtime', xlabel="Date", y=column, ylabel=label, kind='line', marker='o',linewidth=2,legend=False, ax=ax)

This creates a figure with n plots, but it plots all of the points on the top row.

Zephyr
  • 11,891
  • 53
  • 45
  • 80
p3hndrx
  • 103
  • 9
  • 3
    `df.pivot(index='runtime', columns='name', values='grade').plot(subplots=True, layout=(7, 1), figsize=(6, 9))` and make sure to convert `'runtime'` to a datetime dtype with `pd.to_datetime`. Using `pandas 1.3.2` – Trenton McKinney Aug 25 '21 at 20:29
  • 1
    This works and is on one line. It is also scalable with `n`: `df.pivot(index='runtime', columns='name', values='grade').plot(subplots=True, layout=(n, 1), figsize=(6, 9), marker='o',linewidth=2)` – p3hndrx Aug 25 '21 at 22:27

1 Answers1

1

If you have a dataframe like this one:

names = ['Jimmy', 'John', 'Sherry', 'Angela', 'Mary', 'Nathan', 'Albert']
dates = pd.date_range(start = '2021-05-28', end = '2021-08-23', freq = 'D')

df = pd.DataFrame({'runtime': np.repeat(dates, len(names))})
df['name'] = len(dates)*names
df['grade'] = 40 + 20*np.random.random(len(df))
       runtime    name      grade
0   2021-05-28   Jimmy  59.566912
1   2021-05-28    John  40.665274
2   2021-05-28  Sherry  46.436037
3   2021-05-28  Angela  57.563779
4   2021-05-28    Mary  51.033777
..         ...     ...        ...
611 2021-08-23  Sherry  41.600039
612 2021-08-23  Angela  52.228123
613 2021-08-23    Mary  47.629508
614 2021-08-23  Nathan  54.016968
615 2021-08-23  Albert  52.710416

You could use this for loop:

for i, name in enumerate(df['name'].unique(), 0):
    df_filtered = df[df['name'] == name]
    ax[i].plot(df_filtered['runtime'], df_filtered['grade'], marker='o',linewidth=2)
    ax[i].set_ylabel(name)

enter image description here

Zephyr
  • 11,891
  • 53
  • 45
  • 80
  • Thanks for the suggestion! The loop method makes the most sense to me conceptually, iterating through the unique name values. I'm getting an error on run: `NameError: name 'ax' is not defined ` – p3hndrx Aug 25 '21 at 22:31
  • 1
    Got it. I defined ax with: `fig, ax = plt.subplots(nrows=n, figsize=(7, 5), sharex=True)` – p3hndrx Aug 25 '21 at 22:34