0

I am trying to create a multiline stacked plot from .csv file in matplotlib.

My .csv looks like this:

date    person 1    person 2    person 3
3/1/18  45.0        34.0        91.0
3/2/18  88.0        87.0        84.0
3/3/18  56.0        98.0        65.0
3/4/18  34.0        34.0        53.0
3/5/18  56.0        60.0        56.0

This should be simple but I can't get the slicing correct. Here is what I have:

import pandas as pd 
import matplotlib.pyplot as plt

df = pd.read_csv("test.csv")

df.head()

df.plot(xlim=(0, 10)

plt.title('Test')
plt.legend()
plt.show()

I don't want them to be stacked on the same chart. I'd like them to be stacked together like in this link: http://www.k-wave.org/documentation/stackedPlot.php

Would anyone be able to help?

I read through this: Make a multiline plot from .CSV file in matplotlib but not a lot of it is making sense to me because of how this person wanted to plot it. Mine seems more simple and straightforward.

1 Answer 1

0

In principle the desired plot can be achieved as follows.

  • Normalize the dataframe to the range between 0 and 1,
  • Shift each column by one more unit
  • plot the dataframe

Complete example:

u ="""date    person 1    person 2    person 3
3/1/18  45.0        34.0        91.0
3/2/18  88.0        87.0        84.0
3/3/18  56.0        98.0        65.0
3/4/18  34.0        34.0        53.0
3/5/18  56.0        60.0        56.0"""

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

df = pd.read_csv(io.StringIO(u), sep="\s\s+", engine="python")
df["date"] = pd.to_datetime(df["date"], format="%m/%d/%y")
df = df.set_index("date")

# normalize
df /= df.values.max()
# shift colums
df += np.arange(len(df.columns))

ax = df.plot()
ax.set_yticks(np.arange(len(df.columns)))
ax.set_yticklabels(df.columns)
plt.show()

enter image description here

Note how the plot is pretty hard to read. So as an alternative one could plot 3 individual plots, such that the data scales are preserved, using subplots=True:

u ="""date    person 1    person 2    person 3
3/1/18  45.0        34.0        91.0
3/2/18  88.0        87.0        84.0
3/3/18  56.0        98.0        65.0
3/4/18  34.0        34.0        53.0
3/5/18  56.0        60.0        56.0"""

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

df = pd.read_csv(io.StringIO(u), sep="\s\s+", engine="python")
df["date"] = pd.to_datetime(df["date"], format="%m/%d/%y")
df = df.set_index("date")

ax = df.plot(subplots=True)

plt.show()

enter image description here

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

1 Comment

Hi thank you so much for the help! I ran into few issues but figured out I needed to format that data like you did. Which worked! I also figured out to use ax = df.plot(figsize(10,20), subplots=True) to change the figure size. And this ax.legend(bbox_to_anchor=(1.05, 1), loc=2, borderaxespad=0.) to adjust the legend size! Thank you for all your help! I need to understand normalizing the dataframe more . I don’t understand what you mean by range between 0 and 1, so I plan to google and see what comes up!

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.