Can you make 4 bars with 4 columns of data using matplotlib? - pandas

I need to make a bar graph where x-axis plot the index ([1992,1993,1994,1995]) and y-axis will plot 4 columns of random data as shown below. It will generate 4 bars for 4 columns of data. How can I do that? I am pretty new to matplotlib. Please help. This is the DataFrame:
np.random.seed(12345)
df = pd.DataFrame([np.random.normal(32000,200000,3650), np.random.normal(43000,100000,3650), np.random.normal(43500,140000,3650),np.random.normal(48000,70000,3650)], index=[1992,1993,1994,1995])
df.head()

Related

Graph plotting in pandas and seaborn

I have the table with 5 columns with 8000 rows:
Market DeliveryWindowID #Orders #UniqueShoppersAvailable #UniqueShoppersFulfilled
NY 296 2 2 5
MA 365 3 4 8
How do I plot a graph in pandas or seaborn that will show the #Order, #UniqueShoppersAvailable, #UniqueShoppersFulfilled v/s the market and delivery window?
Using Seaborn, reshape your dataframe with melt first:
df_chart = df.melt(['Market','DeliveryWindowID'])
sns.barplot('Market', 'value',hue='variable', data=df_chart)
Output:
One way is to set Market as index forcing it onto the x axis and do a bar graph if you wanted a quick visualization. This can be stacked or not.
Not Stacked
import matplotlib .pyplot as plt
df.drop(columns=['DeliveryWindowID']).set_index(df.Market).plot(kind='bar')
Stacked
df.drop(columns=['DeliveryWindowID']).set_index(df.Market).plot(kind='bar', stacked=True)

How to plot in pandas - Different x and different y axis in a same plot

I want to plot different values of x and y-axis from different CSVs into a simple plot.
csv1:
Time Buff
1 5
2 10
3 15
csv2:
Time1 Buff1
2 3
4 6
5 9
I have 5 different CSVs. I tried plotting to concatenate the dataframes into a single frame and plot it. But I was able to plot with only one x-axis:
df = pd.read_csv('csv1.txt)
df1 = pd.read_csv('csv2.txt)
join = pd.concat([df, df1], axis=1)
join.plot(x='Time', y=['Buff', 'Buff1'], kind='line')
join.plot(x='Time', y='Buff', x='Time1', y='Buff1') #doesn't work
I end up getting a plot with reference with only one x-axis (csv1). But how to plot both x and y column from the CSVs into the same plot?
you can plot two dataframes in the same axis if you specify that axis with ax=. Notice that I created the figure and axis using subplots before i plotted either of the dataframes.
import pandas as pd
import matplotlib.pyplot as plt
f,ax = plt.subplots()
df = pd.DataFrame({'Time':[1,2,3],'Buff':[5,4,3]})
df1 = pd.DataFrame({'Time1':[2,3,4],'Buff1':[5,7,8]})
df.plot(x='Time',y='Buff',ax=ax)
df1.plot(x='Time1',y='Buff1',ax=ax)

Line plot of two different grouped by dataframes

I have grouped data in 2 separate dataframes and want to plot them together with 2 separate lines in one plot.
I have grouped the data as I needed and plotted separate graphs based on the grouped data.
grouped_men = df_men.groupby('age').mean()[['oldpeak']]
grouped_women = df_women.groupby('age').mean()[['oldpeak']]
grouped_men.plot(kind='line',title='Mens age vs oldpeak')
grouped_women.plot(kind='line',title='Womens age vs oldpeak')
But now instead of 2 separate plots, i need to plot one single graph with 2 lines of both men and women.
Current plot look like this:
You need to specify axes where Pandas should put the plots. Try the following:
import matplotlib.pyplot as plt
fig = plt.figure()
ax = fig.add_subplot(111)
grouped_men.plot(kind='line', ax=ax, label='Mens age vs oldpeak')
grouped_women.plot(kind='line', ax=ax, label='Womens age vs oldpeak')
plt.gca().legend(title="Legend title") # Changes
plt.show()

plot a stacked bar chart matplotlib pandas

I want to plot this data frame but I get an error.
this is my df:
6month final-formula Question Text
166047.0 1 0.007421 bathing
166049.0 1 0.006441 dressing
166214.0 1 0.001960 feeding
166216.0 2 0.011621 bathing
166218.0 2 0.003500 dressing
166220.0 2 0.019672 feeding
166224.0 3 0.012882 bathing
166226.0 3 0.013162 dressing
166229.0 3 0.008821 feeding
160243.0 4 0.023424 bathing
156876.0 4 0.000000 dressing
172110.0 4 0.032024 feeding
how can I plot a stacked bar based on the Question text?
I tried some codes but raises error.
dffinal.groupby(['6month','Question Text']).unstack('Question Text').plot(kind='bar',stacked=True,x='6month', y='final-formula')
import matplotlib.pyplot as plt
plt.show()
Actually I want the 6month column be in the x-axis, final-formula in the y-axis and Question text being stacked.
so as here I have three kind of Question text, three stacked bar should be there. and as I have 4 month, 4 bars totally.
Something like this but I applied this and did not work.
Am I missing something?
this picture is without stacking them. its like all question text has been summed up. I want for each Question Text there be stacked.
You missed aggregation step after groupby, namely, sum()
df = dffinal.groupby(['6month','Question Text']).sum().unstack('Question Text')
df.columns = df.columns.droplevel()
df.plot(kind='bar', stacked=True)
I dropped multiindex level from columns just for legend consistency.

Overlaying actual data on a boxplot from a pandas dataframe

I am using Seaborn to make boxplots from pandas dataframes. Seaborn boxplots seem to essentially read the dataframes the same way as the pandas boxplot functionality (so I hope the solution is the same for both -- but I can just use the dataframe.boxplot function as well). My dataframe has 12 columns and the following code generates a single plot with one boxplot for each column (just like the dataframe.boxplot() function would).
fig, ax = plt.subplots()
sns.set_style("darkgrid", {"axes.facecolor":"darkgrey"})
pal = sns.color_palette("husl",12)
sns.boxplot(dataframe, color = pal)
Can anyone suggest a simple way of overlaying all the values (by columns) while making a boxplot from dataframes?
I will appreciate any help with this.
This hasn't been added to the seaborn.boxplot function yet, but there's something similar in the seaborn.violinplot function, which has other advantages:
x = np.random.randn(30, 6)
sns.violinplot(x, inner="points")
sns.despine(trim=True)
A general solution for the boxplot for the entire dataframe, which should work for both seaborn and pandas as their are all matplotlib based under the hood, I will use pandas plot as the example, assuming import matplotlib.pyplot as plt already in place. As you have already have the ax, it would make better sense to just use ax.text(...) instead of plt.text(...).
In [35]:
print df
V1 V2 V3 V4 V5
0 0.895739 0.850580 0.307908 0.917853 0.047017
1 0.931968 0.284934 0.335696 0.153758 0.898149
2 0.405657 0.472525 0.958116 0.859716 0.067340
3 0.843003 0.224331 0.301219 0.000170 0.229840
4 0.634489 0.905062 0.857495 0.246697 0.983037
5 0.573692 0.951600 0.023633 0.292816 0.243963
[6 rows x 5 columns]
In [34]:
df.boxplot()
for x, y, s in zip(np.repeat(np.arange(df.shape[1])+1, df.shape[0]),
df.values.ravel(), df.values.astype('|S5').ravel()):
plt.text(x,y,s,ha='center',va='center')
For a single series in the dataframe, a few small changes is necessary:
In [35]:
sub_df=df.V1
pd.DataFrame(sub_df).boxplot()
for x, y, s in zip(np.repeat(1, df.shape[0]),
sub_df.ravel(), sub_df.values.astype('|S5').ravel()):
plt.text(x,y,s,ha='center',va='center')
Making scatter plots is also similar:
#for the whole thing
df.boxplot()
plt.scatter(np.repeat(np.arange(df.shape[1])+1, df.shape[0]), df.values.ravel(), marker='+', alpha=0.5)
#for just one column
sub_df=df.V1
pd.DataFrame(sub_df).boxplot()
plt.scatter(np.repeat(1, df.shape[0]), sub_df.ravel(), marker='+', alpha=0.5)
To overlay stuff on boxplot, we need to first guess where each boxes are plotted at among xaxis. They appears to be at 1,2,3,4,..... Therefore, for the values in the first column, we want them to be plot at x=1; the 2nd column at x=2 and so on.
Any efficient way of doing it is to use np.repeat, repeat 1,2,3,4..., each for n times, where n is the number of observations. Then we can make a plot, using those numbers as x coordinates. Since it is one-dimensional, for the y coordinates, we will need a flatten view of the data, provided by df.ravel()
For overlaying the text strings, we need a anther step (a loop). As we can only plot one x value, one y value and one text string at a time.
I have the following trick:
data = np.random.randn(6,5)
df = pd.DataFrame(data,columns = list('ABCDE'))
Now assign a dummy column to df:
df['Group'] = 'A'
print df
A B C D E Group
0 0.590600 0.226287 1.552091 -1.722084 0.459262 A
1 0.369391 -0.037151 0.136172 -0.772484 1.143328 A
2 1.147314 -0.883715 -0.444182 -1.294227 1.503786 A
3 -0.721351 0.358747 0.323395 0.165267 -1.412939 A
4 -1.757362 -0.271141 0.881554 1.229962 2.526487 A
5 -0.006882 1.503691 0.587047 0.142334 0.516781 A
Use the df.groupby.boxplot(), you get it done.
df.groupby('Group').boxplot()