I want to improve my code. Is it possible to get the plot without repeating the same instructions multiple lines?
The data comes from a Pandas' dataframe, but I am only plotting the last column (Total Acc.)
e=df['Total Acc'].round(4)*100
#The repetitions start:
row_awa = e.loc['AWA']
row_rem = e.loc['REM']
row_s1 = e.loc['S1']
row_s2 = e.loc['S2']
row_sws = e.loc['SWS']
row_stades = e.loc['stades']
#More repetitions
row_awa.plot()
row_rem.plot()
row_s1.plot()
row_s2.plot()
row_sws.plot()
row_stades.plot()
myLegend=plt.legend(bbox_to_anchor=(0., 1.2, 1., .102), prop ={'size':10}, loc=10, ncol=4, #left, bottom, width, height
title=r'TOTAL ACCURACY FOR MANY K-FOLD') #loc='center'
myLegend.get_title().set_fontsize('20')
3 Answers 3
To reduce the repetitions you could make use of lists by doing something like:
labels = ['AWA', 'REM', 'S1', 'S2', 'SWS', 'stades']
rows = []
for label in labels:
rows.append(e.loc[label])
# or even shorter with list comprehension
rows = [e.loc[label] for label in labels]
for row in rows:
row.plot()
Edit: The labels
list can also be used as first argument of the legend
function to show the correct labels.
-
\$\begingroup\$ Only Option 2 works. But that is fine. Also, how can I add the labels in the legend? So that instead of "Total Acc" I get the correct labels? \$\endgroup\$Aizzaac– Aizzaac2016年10月17日 19:31:04 +00:00Commented Oct 17, 2016 at 19:31
-
\$\begingroup\$ You could use a dictionary instead of a list and use the
iteritems
method of a dictionary but even more simple, probably you can uselabels
as the first argument ofplt.legend
. \$\endgroup\$Jan Kuiken– Jan Kuiken2016年10月17日 19:47:15 +00:00Commented Oct 17, 2016 at 19:47 -
\$\begingroup\$ You might want to add that part to the answer, comments are not permanent and this did answer a part of OP's question. \$\endgroup\$Graipher– Graipher2016年10月18日 07:34:40 +00:00Commented Oct 18, 2016 at 7:34
You simply need to slice your frame using the list of the zero level index of the data you're interested in. Drop the zero level index of that selection
import matplotlib.pyplot as plt
import pandas as pd
level0indexes = ['AWA', 'REM', 'S1', 'S2', 'SWS', 'stades']
cols = ['Total Acc']
slicedf = df.loc[level0indexes, cols].reset_index(level = 0,drop=True).round(4)*100
x = list(range(len(slicedf)))
plt.xticks(x, slicedf.index.tolist())
plt.plot(slicedf.values.flatten(),label=cols[0])
plt.legend()
plt.show()
or even simpler, use pandas plot
import matplotlib.pyplot as plt
import pandas as pd
level0indexes = ['AWA', 'REM', 'S1', 'S2', 'SWS', 'stades']
cols = ['Total Acc']
slicedf = df.loc[level0indexes, cols].reset_index(level = 0,drop=True).round(4)*100
plt.figure();
slicedf.plot();
plt.show();
The second method will allow you to choose to plot more than one column, just add the extra column names to the cols list
You can simply use loc After unstacking.
no need for forloops.
In your code:
e=df['Total Acc'].round(4)*100
e.unstack().loc[['AWA', 'REM', 'S1', 'S2', 'SWS', 'stades']].T.plot()
PS. Some code I made to reproduce the concept:
import numpy as np
import pandas as pd
# generate multiindex
idx = []
for letter in 'abcdefghij':
for num in range(10):
idx.append((letter,num))
# build dataframe
data = pd.DataFrame(np.random.rand(100,10),
index=pd.Index(idx))
# select 1 column, unstack, choose rows and plot.
data[0].unstack().loc['a b d e g h'.split()].T.plot()
Explore related questions
See similar questions with these tags.