I am trying to loop over a df to plot some data in subplots. The columns of my data are a letter, plus an integer.
df = {'x1': [2, 4, 7, 5, 6],
'x2': [2, 7, 2, 6, 3],
'y1': [4, 3, 2, 8, 7],
'y2': [2, 2, 4, 6, 4],
'z1': [2, 2, 2, 6, 7],
'z2': [3, 1, 4, 5, 9]}
df = pd.DataFrame(df, index=range(0,5))
letterlist=['x', 'y', 'z']
numberlist=['1', '2']
tickers = df.columns
where index of df are a set of dates in my df
I am trying to achieve subplots twofold: 1) one section of code for A, B and C, (each plot will have 2 lines in) 2) another piece of code for 1 and 2, (each plot will have 3 lines in, X Y and Z)
I was trying to loop over letterlist and numberlist, because my df is quite a lot larger:
so I attempted:
fig = plt.figure(figsize=(8,8))
for ticker, num in zip(tickers, xrange(1,len(letterlist))):
ax = fig.add_subplot(len(letterlist),1,num)
ax.plot(df[ticker])
ax.set_title(ticker)
plt.tight_layout()
plt.show()
But I keep getting errors and my indexation is wrong i think.. so getting stuck. Any ideas, please?
Expected output is: fig1 1x3 subplot, with x1 and x2 plotted, y1 and y2, and z1 and z2 fig2 1x2 subplot, with x1, y1 and z1 plotted, and x2, y2, and z2
Thanks
-
1Count your parantheses.Stop harming Monica– Stop harming Monica2018年08月27日 09:56:23 +00:00Commented Aug 27, 2018 at 9:56
-
Thanks Goyo, I updated the question. Sorry I wasn't clear enough - the issue I have is that I don't know how to create a new subplot as described in the desired output... my code returns a subplot for x1, x2, y1, y2, z1 and z2, which isn't desired output. Any ideas?Junaid Mohammad– Junaid Mohammad2018年08月27日 10:03:14 +00:00Commented Aug 27, 2018 at 10:03
-
@Mr.T Its more than a typo error. (Im sorry I had a small typo in my dummy question). Please see my comment above. Can u help? Im not actually sure how to re-open questionsJunaid Mohammad– Junaid Mohammad2018年08月27日 10:09:19 +00:00Commented Aug 27, 2018 at 10:09
-
Now I do not see any errors when running your code. But there is no way you get two figures if you only create one. You do not need to re-open the question.Stop harming Monica– Stop harming Monica2018年08月27日 10:20:58 +00:00Commented Aug 27, 2018 at 10:20
-
@Goyo, thank you for replying. The above was a snippet of me trying to tackle 1) first. You will see that the code produces an output of x1 plotted on subplot 1, whilst x2 is plotted on subplot 2. What I wanted was 1x3 subplot, with x1 and x2 plotted on sub1, y1 and y2 on sub2, and z1 and z2 on sub3Junaid Mohammad– Junaid Mohammad2018年08月27日 10:25:42 +00:00Commented Aug 27, 2018 at 10:25
1 Answer 1
One way to achieve your desired output is this:
from matplotlib import pyplot as plt
import pandas as pd
#define the dataframe
df = {'x1': [2, 4, 7, 5, 6],
'x2': [2, 7, 2, 6, 3],
'y1': [4, 3, 2, 8, 7],
'y2': [2, 2, 4, 6, 4],
'z1': [2, 2, 2, 6, 7],
'z2': [3, 1, 4, 5, 9]}
df = pd.DataFrame(df, index=range(0,5))
letters = 3
numbers = 2
tickers = df.columns
#first figure letterwise presentation
fig, axes = plt.subplots(nrows = letters, ncols = 1, figsize=(8,8))
for i, pair in enumerate([tickers[i:i+numbers] for i in range(0, len(tickers), numbers)]):
ax = axes[i]
for item in pair:
ax.plot(df[item], label = item)
ax.legend()
ax.set_title(", ".join(pair))
plt.tight_layout()
#second figure numberwise presentation
fig, axes = plt.subplots(nrows = numbers, ncols = 1, figsize=(8,8))
for i, pair in enumerate([tickers[i::numbers] for i in range(numbers)]):
ax = axes[i]
for item in pair:
ax.plot(df[item], label = item)
ax.legend()
ax.set_title(", ".join(pair))
plt.tight_layout()
plt.show()
Sample output: enter image description here
But you still have to define manually, how many letters and numbers you have and your columns have to be in the expected order [x1, x2, x3, ..., xn, y1, y2, y3,...,yn, z1...]. You might want to look into pandas multiindex to construct a dataframe, where you can automatically extract the necessary information.
-
Thank you Mr. T I will indeed look into multi-indexing, thank youJunaid Mohammad– Junaid Mohammad2018年08月27日 11:55:57 +00:00Commented Aug 27, 2018 at 11:55