Annotate labels in pandas scatter plot - pandas

I saw this method from an older post but can't get the plot I want.
To start
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
import string
df = pd.DataFrame({'x':np.random.rand(10),'y':np.random.rand(10)},
index=list(string.ascii_lowercase[:10]))
scatter plot
ax = df.plot('x','y', kind='scatter', s=50)
Then define a function to iterate the rows to annotate
def annotate_df(row):
ax.annotate(row.name, row.values,
xytext=(10,-5),
textcoords='offset points',
size=18,
color='darkslategrey')
Last apply to get annotation
ab= df.apply(annotate_df, axis=1)
Somehow I just get a series ab instead of the scatter plot I want. Where is wrong? Thank you!

Your code works, you just need plt.show() at the end.
Your full code:
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
import string
df = pd.DataFrame({'x':np.random.rand(10),'y':np.random.rand(10)},
index=list(string.ascii_lowercase[:10]))
ax = df.plot('x','y', kind='scatter', s=50)
def annotate_df(row):
ax.annotate(row.name, row.values,
xytext=(10,-5),
textcoords='offset points',
size=18,
color='darkslategrey')
ab= df.apply(annotate_df, axis=1)
plt.show()

Looks like that this doesn't work any more, however the solution is easy: convert row.values from numpy.ndarray to list:
list(row.values)

Related

matplotlib.axis.axes error in mplfinance for volume

I am working with stock data which looks like daily.head
My code is:
import pandas as pd
import mplfinance as mpf
import matplotlib.pyplot as plt
data = pd.read_csv('/content/drive/MyDrive/python/TEchAnalysis.csv')
figdims=(15,10)
fig , ax = plt.subplots(figsize=figdims)
mpf.plot(daily , type='candle' , mav=(5,10,20,50,100) ,volume=True , ax=ax )
I am having the error
ValueError: `volume` must be of type `matplotlib.axis.Axes`
Please can somebody explain me this error & how to fix it?
If you specify external axes, you should also specify axes to display the volume. According to the documentation about external axes:
Please note the following:
Use kwarg ax= to pass any matplotlib Axes that you want into mpf.plot()
If you also want to plot volume, then you must pass in an Axes instance for the volume, so instead of volume=True, use volume=<myVolumeAxesInstance><myVolumeAxesInstance>.
If you specify ax= for mpf.plot() then you must also specify ax= for all calls to make_addplot().
Try this:
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
import mplfinance as mpf
import pandas as pd
import yfinance as yf
%matplotlib inline
df = yf.download('aapl', '2015-01-01', '2021-01-01')
df.rename(columns= {'Adj Close': 'Adj_close'}, inplace= True)
df1 = df.copy().loc['2015-01':'2015-02', :]
fig, ax1 = plt.subplots(figsize= (12, 6))
fig.set_facecolor('#ffe8a8')
ax1.set_zorder(1)
ax1.grid(True, color= 'k', linestyle= '--')
ax1.set_frame_on(False)
ax2 = ax1.twinx()
ax2.grid(False)
mpf.plot(df1, ax= ax1, type= 'candle', volume= ax2, xlim= (df1.index[0],
df1.index[-1]))
plt.show()
It works fairly well, giving some options to customize.
This is the output:

Understanding plt.show() in Matplotlib

import numpy as np
import os.path
from skimage.io import imread
from skimage import data_dir
img = imread(os.path.join(data_dir, 'checker_bilevel.png'))
import matplotlib.pyplot as plt
#plt.imshow(img, cmap='Blues')
#plt.show()
imgT = img.T
plt.figure(1)
plt.imshow(imgT,cmap='Greys')
#plt.show()
imgR = img.reshape(20,5)
plt.figure(2)
plt.imshow(imgR,cmap='Blues')
plt.show(1)
I read that plt.figure() will create or assign the image a new ID if not explicitly given one. So here, I have given the two figures, ID 1 & 2 respectively. Now I wish to see only one one of the image.
I tried plt.show(1) epecting ONLY the first image will be displayed but both of them are.
What should I write to get only one?
plt.clf() will clear the figure
import matplotlib.pyplot as plt
plt.plot(range(10), 'r')
plt.clf()
plt.plot(range(12), 'g--')
plt.show()
plt.show will show all the figures created. The argument you forces the figure to be shown in a non-blocking way. If you only want to show a particular figure you can write a wrapper function.
import matplotlib.pyplot as plt
figures = [plt.subplots() for i in range(5)]
def show(figNum, figures):
if plt.fignum_exists(figNum):
fig = [f[0] for f in figures if f[0].number == figNum][0]
fig.show()
else:
print('figure not found')

Legend not showing when plotting multiple seaborn plots

I typically don't have problems with matplotlib legend, but this is the first time I am using it with multiple seaborn plots, and the following does not work.
fig = plt.figure(figsize=(10,6))
a =sns.regplot(x='VarX', y='VarY1', data=data)
b = sns.regplot(x='VarX', y='VarY2', data=data)
c = sns.regplot(x='VarX', y='VarY3', data=data)
fig.legend(handles=[a, b, c],labels=['First','Second','Third'])
fig.show()
What am I doing wrong?
seaborn.regplot returns an axes. You cannot create a legend proxy handle from an axes. However this is not even necessary. Remove the handles from the legend and it should give the desired plot.
import matplotlib.pyplot as plt
import numpy as np; np.random.seed(1)
import pandas as pd
import seaborn as sns
data=pd.DataFrame({"VarX" : np.arange(10),
'VarY1': np.random.rand(10),
'VarY2': np.random.rand(10),
'VarY3': np.random.rand(10)})
fig = plt.figure(figsize=(10,6))
sns.regplot(x='VarX', y='VarY1', data=data)
sns.regplot(x='VarX', y='VarY2', data=data)
sns.regplot(x='VarX', y='VarY3', data=data)
fig.legend(labels=['First','Second','Third'])
plt.show()

matplotlib adding string to a an axis

import matplotlib.pyplot as plt
import numpy as np
ydata = [55,60,65,70,75,80]
xdata = [1,2,3,4,5,6]
plt.plot(xdata, ydata)
set(plt.gca,'XTickLabel',{'Jan','Feb','Mar','April','May','June'})
plt.show()
I am using matplotlib and trying to add text values to appear on the x axis.
I have tried to use the following code but get the following error message
set(plt.gca,'XTickLabel',
{'Jan','Feb','Mar','April','May','June'})
TypeError: set expected at most 1 arguments, got 3 I am not sure what this
is referring get current access I have set the value
Sets are a Python data structure, it has nothing to do with what you want here, you only need to use ax.set_xticklabels and ax.set_xticks to ensure all of them show in the plot:
import matplotlib.pyplot as plt
import numpy as np
fig, ax = plt.subplots()
ydata = [55,60,65,70,75,80]
xdata = [1,2,3,4,5,6]
ax.set_xticks(xdata)
ax.set_xticklabels(['Jan','Feb','Mar','April','May','June'])
plt.plot(xdata, ydata)
plt.show()

My pandas-generated subplots are layouted incorrectly

I ran the following code to get two plots next to each other (it is a minimal working example that you can copy):
import pandas as pd
import numpy as np
from matplotlib.pylab import plt
comp1 = np.random.normal(0,1,size=200)
values = pd.Series(comp1)
plt.close("all")
f = plt.figure()
plt.show()
sp1 = f.add_subplot(2,2,1)
values.hist(bins=100, alpha=0.5, color="r", normed=True)
sp2 = f.add_subplot(2,2,2)
values.plot(kind="kde")
Unfortunately, I then get the following image:
This is also an interesting layout, but I wanted the figures to be next to each other. What did I do wrong? How can I correct it?
For clarity, I could also use this:
import pandas as pd
import numpy as np
from matplotlib.pylab import plt
comp1 = np.random.normal(0,1,size=200)
values = pd.Series(comp1)
plt.close("all")
fig, axes = plt.subplots(2,2)
plt.show()
axes[0,0].hist(values, bins=100, alpha=0.5, color="r", normed=True) # Until here, it works. You get a half-finished correct image of what I was going for (though it is 2x2 here)
axes[0,1].plot(values, kind="kde") # This does not work
Unfortunately, in this approach axes[0,1] refers to the subplot that has a plot method but does not know kind="kde". Please take into consideration that the in the first version plot is executed on the pandas object, whereas in the second version plot is executed on the subplot, which does not work with the kind="kde" parameter.
use ax= argument to set which subplot object to plot:
import pandas as pd
import numpy as np
from matplotlib.pylab import plt
comp1 = np.random.normal(0,1,size=200)
values = pd.Series(comp1)
plt.close("all")
f = plt.figure()
sp1 = f.add_subplot(2,2,1)
values.hist(bins=100, alpha=0.5, color="r", normed=True, ax=sp1)
sp2 = f.add_subplot(2,2,2)
values.plot(kind="kde", ax=sp2)