plt.show() does not print plt.plot only plt.scatter - python

So, for the following code no graph is printed in jupyter notebook. If I use plt.scatter then it does produce graph. Any suggestions what could be wrong? Can it be caused by the data?
import pandas as pd
import numpy as np
import matplotlib
import matplotlib.pyplot as plt
def calc_gauss(df, index):
x=df.iloc[[index]]
mean = df.apply(lambda x: x.mean(), axis=1)
mu=mean.iloc[[index]]
std = df.std(axis=1)
sig=std.iloc[[index]]
dens = norm.pdf(x,mu,sig)
# build the plot
fig, ax = plt.subplots(figsize=(9,6))
plt.style.use('fivethirtyeight')
ax.plot(x, dens)
return plt.show()
calc_gauss(df_distance, 339)

Instead of
return plt.show()
use
fig.show()
If you want the picture to show in the notebook, use %matplotlib inline in a cell evaluated before the show command
Note the problem was that the arrays were shape (1,24). plot likes only 1D arrays. Replacing ax.plot(x, dens) with ax.plot(x.reshape(-1), dens.reshape(-1)) solved the issue.

Related

Not able to plot box plot separately

I have lot of feature in data and i want to make box plot for each feature. So for that
import pandas as pd
import seaborn as sns
plt.figure(figsize=(25,20))
for data in train_df.columns:
plt.subplot(7,4,i+1)
plt.subplots_adjust(hspace = 0.5, wspace = 0.5)
ax =sns.boxplot(train_df[data])
I did this
and the output is
All the plot are on one image i want something like
( not with skew graphs but with box plot )
What changes i need to do ?
In your code, I cannot see where the i is coming from and also it's not clear how ax was assigned.
Maybe try something like this, first an example data frame:
import pandas as pd
import numpy as np
import seaborn as sns
from matplotlib import pyplot as plt
train_df = pd.concat([pd.Series(np.random.normal(i,1,100)) for i in range(12)],axis=1)
Set up fig and a flattened ax for each subplot:
fig,ax = plt.subplots(4,3,figsize=(10,10))
ax = ax.flatten()
The most basic would be to call sns.boxplot assigning ax inside the function:
for i,data in enumerate(train_df.columns):
sns.boxplot(train_df[data],ax=ax[i])

Matplotlib inline in Jupyter - how to contol when the plot is shown?

I have a function that creates a figure and for some reason it is shown in Jupyter notebook twice, even though I didn't run show at all. I pass the fig and ax as an output of this function, and plan to show it only later.
I get confused between plt, fig and ax functionaries and guess that the answer is hidden somewhere there.
Here is an anonymised version of my code:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
%matplotlib inline
def plot_curve(dummydata):
# builds a chart
fig,ax = plt.subplots(1) # get subplots
fig.set_figheight(7)
fig.set_figwidth(12) #set shape
plt.plot(dummydata.x1, dummydata.y1,label = 'l1') #curve 1
plt.plot(dummydata.x2, dummydata.y2,label = 'l2') #curve2
plt.xlabel('xlabel') #labels
plt.ylabel('xlabel')
plt.yscale('linear') #scale and bounds
plt.ylim(0,100)
ymin,ymax= ax.get_ylim()
ax.axhline(1, color='k', linestyle=':', label = 'lab1') #guideline - horizontal
ax.axvline(2, color='r',linestyle='--', label = 'lab2') #guideline - vertical
ax.axvline(3, color='g',linestyle='--', label = 'lab3') #guideline - vertical
ax.arrow(1,2,3,0, head_width=0.1, head_length=0.01, fc='k', ec='k') # arrow
rect = mpl.patches.Rectangle((1,2), 2,3, alpha = 0.1, facecolor='yellow',
linewidth=0 , label= 'lab4') #yellow area patch
ax.add_patch(rect)
plt.legend()
plt.title('title')
return fig,ax
and then call it with:
for i in range(3):
dummydata = pd.DataFrame({
'x1':np.arange(1+i,100,0.1),
'y1':np.arange(11+i,110,0.1),
'x2':np.arange(1+i,100,0.1),
'y2':np.arange(21+i,120,0.1)
})
fig,ax = plot_curve(dummydata) #get the chart
What should I change to not show the figure by default, and show it only by my command?
Thanks
Try disabling matplotlib interactive mode using plt.ioff(). With interactive mode disabled the plots will only be shown with an explicit plt.show().
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
%matplotlib inline
# Desactivate interactive mode
plt.ioff()
def plot_curve(dummydata):
# the same code as before
Then in another cell
for i in range(3):
dummydata = pd.DataFrame({
'x1':np.arange(1+i,100,0.1),
'y1':np.arange(11+i,110,0.1),
'x2':np.arange(1+i,100,0.1),
'y2':np.arange(21+i,120,0.1)
})
# I'am assuming this should not be in the for loop
# The plot will NOT be shown because we are not in interactive mode
fig, ax = plot_curve(dummydata) #get the chart
No plot will be shown yet.
Now in another cell
# Now ANY plot (figure) which was created and not shown yet will be finally shown
plt.show()
The plot is finally shown. Note that if you have created several plots all of them will be shown now.
Try this:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
%matplotlib
With this importing you should not see the figure after plotting.
But you can see the figure by writing fig to IPython cell:
dummydata = pd.DataFrame({
'x1':np.arange(1,100,0.1),
'y1':np.arange(11,110,0.1),
'x2':np.arange(1,100,0.1),
'y2':np.arange(21,120,0.1)
})
fig,ax = plot_curve(dummydata) #get the chart
fig # Will now plot the figure.
Is this the desired output?

matplotlib.pyplot plot the wrong order of y-label

I tried to plot a bar figure and I want x-label to remain the specific order, so I use set_xticklabels. However, the result turns out the y-value didn't match the x-label.
import matplotlib.pyplot as plt
A=['Dog','Cat','Fish','Bird']
B=[26,39,10,20]
fig=plt.figure()
ax1 = fig.add_subplot(1,1,1)
ax1.bar(A, B)
ax1.set_xticklabels(A)
plt.title("Animals")
plt.show()
The expected result is Dog=26 Cat=39 Fish=10 Bird=20, but the result I got is Dog=20 Cat=39 Fish=26 Bird=20.
Here is one answer I found. However, if I use this method I cannot keep the original order I want.
import itertools
import matplotlib.pyplot as plt
A=['Dog','Cat','Fish','Bird']
B=[26,39,10,20]
lists = sorted(itertools.izip(*[A, B]))
new_x, new_y = list(itertools.izip(*lists))
fig=plt.figure()
ax1 = fig.add_subplot(1,1,1)
ax1.bar(new_x, new_y )
ax1.set_xticklabels(new_x)
plt.title("Animals")
plt.show()
Is there any way I can keep the original order of x-label and make y value match with x?
This code will serve the purpose,
import numpy as np
import matplotlib.pyplot as plt
A=['Dog','Cat','Fish','Bird']
B=[26,39,10,20]
y_pos = np.arange(len(A))
plt.bar(y_pos, B)
plt.xticks(y_pos, A)
plt.title("Animals")
plt.show()
Why don't you use pandas for storing your data:
import pandas as pd
import matplotlib
A= ['Dog','Cat','Fish','Bird']
B= [26,39,10,20]
ser = pd.Series(index=A, values=B)
ax = ser.loc[A].plot(kind='bar', legend=False)
ax.set_ylabel("Value")
ax.set_xlabel("Animals")
plt.show()
In matplotlib 2.2 you can just plot those lists as they are and get the correct result.
import matplotlib.pyplot as plt
A=['Dog','Cat','Fish','Bird']
B=[26,39,10,20]
plt.bar(A, B)
plt.title("Animals")
plt.show()

Showing graph sequentially not just the last one

When I do the following using Pandas on IPython, it only shows the last picture I drawn, is there a way I can let them show sequentially on IPython?
def drawBar(colName):
df1=df[colName].value_counts().plot(kind='bar', title=colName)
drawBar("myBiscuit")
drawBar("myBedRoom")
...(many more drawBar)
For plotting graphs in the notebook, you'd use the IPython magic %matplotlib inline.
(a) Plotting each individual graph one after the other:
You would need to call plt.show() for each graph. This will return a long list of plots in your IPython.
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
%matplotlib inline
colNames = "ABCDEFGHI"
x = np.random.randint(0,5, size=(10, 9))
df = pd.DataFrame(x, columns=[letter for letter in colNames])
def drawBar(colName):
df1=df[colName].value_counts().plot(kind='bar', title=colName)
for i in range(9):
drawBar(colNames[i])
plt.show()
(b) Using subplots.
Creating several subplots can be done with plt.subplots(). Then using the ax keyword argument to the pandas plotting function, creates the graph on the specified axes.
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
%matplotlib inline
colNames = "ABCDEFGHI"
x = np.random.randint(0,5, size=(10, 9))
df = pd.DataFrame(x, columns=[letter for letter in colNames])
fig, axes = plt.subplots(3,3)
def drawBar(colName, ax):
df1=df[colName].value_counts().plot(kind='bar', title=colName, ax=ax)
for i, ax in enumerate(axes.flatten()):
drawBar(colNames[i], ax)
plt.tight_layout()

plotting multiple histograms in grid

I am running following code to draw histograms in 3 by 3 grid for 9 varaibles.However, it plots only one variable.
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
def draw_histograms(df, variables, n_rows, n_cols):
fig=plt.figure()
for i, var_name in enumerate(variables):
ax=fig.add_subplot(n_rows,n_cols,i+1)
df[var_name].hist(bins=10,ax=ax)
plt.title(var_name+"Distribution")
plt.show()
You're adding subplots correctly but you call plt.show for each added subplot which causes what has been drawn so far to be shown, i.e. one plot. If you're for instance plotting inline in IPython you will only see the last plot drawn.
Matplotlib provides some nice examples of how to use subplots.
Your problem is fixed like:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
def draw_histograms(df, variables, n_rows, n_cols):
fig=plt.figure()
for i, var_name in enumerate(variables):
ax=fig.add_subplot(n_rows,n_cols,i+1)
df[var_name].hist(bins=10,ax=ax)
ax.set_title(var_name+" Distribution")
fig.tight_layout() # Improves appearance a bit.
plt.show()
test = pd.DataFrame(np.random.randn(30, 9), columns=map(str, range(9)))
draw_histograms(test, test.columns, 3, 3)
Which gives a plot like:
In case you don't really worry about titles, here's a one-liner
df = pd.DataFrame(np.random.randint(10, size=(100, 9)))
df.hist(color='k', alpha=0.5, bins=10)

Categories

Resources