matplotlib.axis.axes error in mplfinance for volume - pandas

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:

Related

BoxPlot figure is not showing( just getting <AxesSubplot:>)

I am already having Tkinter(someone said to install a tkinter)
code used:
imports are:
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
sns.set()
if u want to view the data-set then it is :
df = pd.read_csv("https://raw.githubusercontent.com/plotly/datasets/master/diabetes.csv")
code used to plot boxplot in jupyter notebook
fig, ax = plt.subplots(figsize = (20,20))
sns.boxplot(data = df,ax = ax)
)
I was supposed to add in my import's
%matplotlib inline

Seaborn boxplot custom lables aside box

I have the code segment given below, and it generates the provided boxplot. I would like to know how to add custom labels aside each box, so that the boxplot is even more digestible to the readers of my result. The expected diagram is also provided. I reckon there should be an easy way to get this done in Seaborn/Matplotlib.
What I exactly want is to add the following labels to each box (on left hand side as in shown in the example provided)
The code use to generate boxplot
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.ticker as MaxNLocator
from matplotlib import rcParams
from matplotlib.ticker import ScalarFormatter, FuncFormatter,FormatStrFormatter, EngFormatter#, mticker
%matplotlib inline
import seaborn as sns
range_stats = pd.read_csv(f'{snappy_data_dir}range_searcg_snappy_stats.csv')
data_stats_rs_txt = range_stats[range_stats['category'] == "t"]
data_stats_rs_seq = range_stats[range_stats['category'] == "s"]
fig, ax =plt.subplots(1,2)
rcParams['figure.figsize'] =8, 6
flierprops = dict(marker='x')
labels1 = ['R1', 'R2', 'R3', 'R4', 'R5']
sns.boxplot(x='Interval',y='Total',data=data_stats_rs_txt,palette='rainbow', ax=ax[0])
sns.boxplot(x='Interval',y='Total',data=data_stats_rs_seq,palette='rainbow', ax=ax[1])
ax[0].set(xlabel='Interval (s)', ylabel='query execution time (s)', title='Text format', ylim=(0, 290))
ax[1].set(xlabel='Interval (s)', ylabel='', title='Proposed format',ylim=(0, 290), yticklabels=[])
plt.savefig("range-query-corrected.svg")
plt.savefig('snappy_compressed_rangesearch.pdf')
Resulted figure:
Expected figure with labels
This might help you, although it is not a fully correct way and is not a complete solution.
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline
tips = sns.load_dataset('tips')
fig, axes = plt.subplots(1, 2, figsize=(12, 4))
sns.set_context('poster',font_scale=0.5)
sns.boxplot(x="day", y="total_bill", data=tips,palette='rainbow', ax=axes[0], zorder=0)
axes[0].text(0, 45, r"$B1$", fontsize=20, color="blue")
axes[0].text(0.9, 45, r"$B2$", fontsize=20, color="blue")
axes[0].text(2.2, 45, r"$B3$", fontsize=20, color="blue")
axes[0].text(3.1, 45, r"$B4$", fontsize=20, color="blue");
sns.boxplot(x="day", y="tip", data=tips,palette='rainbow', ax=axes[1], zorder=10)
iris = sns.load_dataset("iris")
x_var = 'species'
y_var = 'sepal_width'
x_order = ['setosa', 'versicolor', 'virginica']
labels = ['R1','R2','R3']
max_vals = iris.groupby(x_var).max()[y_var].reindex(x_order)
ax = sns.boxplot(x=x_var, y=y_var, data=iris)
for x,y,l in zip(range(len(x_order)), max_vals, labels):
ax.annotate(l, xy=[x,y], xytext=[0,5], textcoords='offset pixels', ha='center', va='bottom')

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()

Annotate labels in pandas scatter plot

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)

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)