Gromulus-Romulus
Gromulus-Romulus

Reputation: 155

Matplotlib: Generating Subplots for Multiple Time Series

I have the following dataset that was randomly generated through a simulation I am building:

https://drive.google.com/drive/folders/1JF5QrliE9s8VPMaGc8Z-mwpFhNWkeYtk?usp=sharing

For debugging purposes, I would like to be able to view this data in a series of small multiples. Like this:

enter image description here

I am attempting to do this using matplotlib and pandas. Here is my code for that:

import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.backends.backend_pdf import PdfPages

def graph_file(f: str):
    """
    Graphs a single file of data
    and exports it as a pdf of separate charts.
    """

    data = pd.read_csv(f)
    header = data.columns

    fname = f[:-4] + '.pdf'

    with PdfPages(fname) as pdf:
        n = len(header)
        time: str = header[0]

        # Multiple charts on one page
        fig = plt.figure()
        for i in range(1, n):
            y: str = header[i]
            ax = fig.add_subplot()
            data.plot(x=time, y=y)
        pdf.savefig(bbox_inches='tight')

When I open up the .csv file and try to run the function using a Jupyter notebook, I get the same deprecation warning over and over again:

<ipython-input-5-0563709f3c08>:24: MatplotlibDeprecationWarning: Adding an axes using the same arguments as a previous axes currently reuses the earlier instance.  In a future version, a new instance will always be created and returned.  Meanwhile, this warning can be suppressed, and the future behavior ensured, by passing a unique label to each axes instance.
  ax = fig.add_subplot()

The resulting pdf file does not contain a single page with multiple graphs (which is what I want like in the first image) but just a single page with a single graph:

enter image description here

What exactly am I doing wrong? I greatly appreciate any feedback you can give.

Upvotes: 0

Views: 1803

Answers (1)

pakpe
pakpe

Reputation: 5479

Here is a solution that should meet your needs. It reads the csv file into a dataframe and iterates through the columns of the dataframe to plot corresponding subplots.

import pandas as pd
import matplotlib.pyplot as plt
from matplotlib.backends.backend_pdf import PdfPages

def graph_file(f: str):
    df = pd.read_csv(f)

    fig, axs = plt.subplots(nrows=3, ncols=3)
    fig.set_size_inches(20, 10)
    fig.subplots_adjust(wspace=0.5)
    fig.subplots_adjust(hspace=0.5)

    fname = f[:-4] + '.pdf'
    with PdfPages(fname) as pdf:
        for col, ax in zip(df.columns[1:], axs.flatten()):
            ax.plot(df['time (days)'], df[col])
            ax.set(xlabel='time (days)', ylabel=col)
            ax.tick_params(axis='x', labelrotation=30)

        pdf.savefig(bbox_inches='tight')
        plt.show()

enter image description here

Upvotes: 1

Related Questions