Legend in subplots() for vertical lines Matplotlib.pyplot Python - python

I am trying to do EDA with the Kaggle dataset link
I made a plot with 3 subplots and have plotted 3 vertical lines on the basis of mean, median and mode. is there any way to show these 3 lines in a legend?
This is my code
def plott(data):
fig, axes = plt.subplots(3, sharex=True, figsize=(15, 15),gridspec_kw={"height_ratios": (1, 0.2, 0.6)})
fig.suptitle('Spread of Data for ' + data.name, fontsize=20, fontweight='bold')
sns.histplot(data, kde=True, binwidth=1, ax=axes[0])
sns.boxplot(x=data, orient='h', ax=axes[1])
sns.violinplot(x=data, ax=axes[2])
axes[0].set_xlabel('')
axes[1].set_xlabel('')
axes[2].set_xlabel('')
axes[0].axvline(data.mean(), color='r', linewidth=2, linestyle='solid')
axes[0].axvline(data.median(), color='r', linewidth=2, linestyle='dashed')
axes[0].axvline(data.mode()[0], color='r', linewidth=2, linestyle='dotted')
axes[1].axvline(data.mean(), color='r', linewidth=2, linestyle='solid')
axes[1].axvline(data.median(), color='r', linewidth=2, linestyle='dashed')
axes[1].axvline(data.mode()[0], color='r', linewidth=2, linestyle='dotted')
axes[2].axvline(data.mean(), color='r', linewidth=2, linestyle='solid')
axes[2].axvline(data.median(), color='r', linewidth=2, linestyle='dashed')
axes[2].axvline(data.mode()[0], color='r', linewidth=2, linestyle='dotted')
axes[0].tick_params(axis='both', which='both', labelsize=10, labelbottom=True)
axes[1].tick_params(axis='both', which='both', labelsize=10, labelbottom=True)
axes[2].tick_params(axis='both', which='both', labelsize=10, labelbottom=True)
plott(df['Age'])
This is the resulting plot
Is there a way to add the legend in here in accordance to the 3 vertical lines
like this with each line type denoting the value?
Also, how to add more values in x axis of all three graphs?
like make it interval of 5 or 2 years apart?
Thanks

Give the axvlines a "label" value, then call plt.legend after plotting it.
Example:
import matplotlib.pyplot as plt
plt.plot([1,2,3],[1,2,3],label="Test")
plt.axvline(x=0.22058956, label="Test2", color="red")
plt.legend()
Output:

Related

How to plot bars next to each other?

I have a histogram with 4 different objects on each bin, that now are stacked on top of each other. Instead, I need to plot the different objects side by side within the same histogram bin (similar to the top left plot in https://matplotlib.org/3.1.1/gallery/statistics/histogram_multihist.html):
bins=np.logspace(np.log10(0.01),np.log10(20), 11)
plt.hist(a[nosfr]/1e+11, bins, color='red', fill=True, linewidth=2, density=True, histtype='bar', edgecolor='k')
plt.hist(a[highsfr]/1e+11, bins, color='orange', fill=True, linewidth=2, density=True, histtype='bar', edgecolor='k')
plt.hist(b[mynosfr]/1e+11, bins, color='blue', edgecolor='k', fill=True, linewidth=2, density=True, alpha=0.7, histtype='bar')
plt.hist(b[myhighsfr]/1e+11, bins, color='cyan', edgecolor='k', fill=True, linewidth=2, density=True, alpha=0.7, histtype='bar')
plt.xscale('log')
plt.xlim(2e-2, 2e+1)
[nosfr], [highsfr] etc. draw objects with different criteria within the same sample (a and b). All the examples I've looked at are slightly different from what I need, and I can't find the right way. Thanks!
Call plot method from your data frame with kind parameter set to bar.
x = np.random.random((10, 4))
df = pd.DataFrame(x, columns=['a', 'b', 'c', 'd'])
df.plot(kind='bar')
This is the result:

X-axis minor gridlines still not showing even after trying all solutions

My x-axis minor gridlines are not showing, this is my code
ax = plt.gca()
ax.minorticks_on()
plt.semilogx(data_x1,data_y1,"red")
plt.semilogx(data_x2,data_y2,"blue")
ax.grid(b=True, which='major',axis="both", color='k', linestyle='-', linewidth=0.5)
ax.grid(b=True, which='minor',axis="both", color='k', linestyle='-', linewidth=0.2)
plt.xlabel("frequency(Hz)")
plt.ylabel("Iramp(dB)")
plt.show()
enter image description here
Either I'm not sure of what you want, or your code is actually working correctly. The minor grid lines are those between the powers of 10. I made a little example to show a comparison of your plot with the minor grid lines on and off.
import numpy as np
import matplotlib.pyplot as plt
data_x1 = np.linspace(0,2,10)
data_x2 = np.linspace(0,4,10)
data_y1 = np.random.rand(10)
data_y2 = np.random.rand(10)
fig, axall =plt.subplots(1,2, figsize=(10,5))
# your code with some changes
ax = axall[0]
ax.minorticks_on()
ax.semilogx(data_x1,data_y1,"red")
ax.semilogx(data_x2,data_y2,"blue")
ax.grid(b=True, which='major',axis="both", color='k', linestyle='-', linewidth=0.5)
ax.grid(b=True, which='minor',axis="both", color='k', linestyle='-', linewidth=0.2)
ax.set_xlabel("frequency(Hz)")
ax.set_ylabel("Iramp(dB)")
# code to make the plot on the right.
ax = axall[1]
ax.minorticks_on()
ax.semilogx(data_x1,data_y1,"red")
ax.semilogx(data_x2,data_y2,"blue")
ax.grid(b=True, which='major',axis="both", color='k', linestyle='-', linewidth=0.5)
# ax.grid(b=True, which='minor',axis="both", color='k', linestyle='-', linewidth=0.2)
ax.set_xlabel("frequency(Hz)")
ax.set_ylabel("Iramp(dB)")
plt.show()
Note how I commented out your minor grid lines.

Set minor ticks in all log-log subplots

I have a figure with two subplots in log-log scale. I would like to plot the minor ticks as well. Even though I have applied different solutions from Stack Overflow, my figure does not look as I want.
One of the solutions I have modified comes from ImportanceOfBeingErnest and the code looks like this:
fig, ((ax1, ax2)) = plt.subplots(1, 2, figsize=(8, 5), sharey=True)
# First plot
ax1.loglog(PLOT1['X'], PLOT1['Y'], 'o',
markerfacecolor='red', markeredgecolor='red', markeredgewidth=1,
markersize=1.5, alpha=0.2)
ax1.set(xlim=(1e-4, 1e4), ylim=(1e-8, 1e2))
ax1.set_xscale("log"); ax1.set_yscale("log")
ax1.xaxis.set_major_locator(matplotlib.ticker.LogLocator(base=10.0, numticks=25))
ax1.yaxis.set_major_locator(matplotlib.ticker.LogLocator(base=10.0, numticks=25))
locmaj = matplotlib.ticker.LogLocator(base=10,numticks=25)
ax1.xaxis.set_major_locator(locmaj)
locmin = matplotlib.ticker.LogLocator(base=10.0,subs=(0.2,0.4,0.6,0.8),numticks=25)
ax1.xaxis.set_minor_locator(locmin)
ax1.xaxis.set_minor_formatter(matplotlib.ticker.NullFormatter())
locmaj = matplotlib.ticker.LogLocator(base=10,numticks=25)
ax1.yaxis.set_major_locator(locmaj)
locmin = matplotlib.ticker.LogLocator(base=10.0,subs=(0.2,0.4,0.6,0.8),numticks=25)
ax1.yaxis.set_minor_locator(locmin)
ax1.yaxis.set_minor_formatter(matplotlib.ticker.NullFormatter())
ax1.set_xlabel('X values', fontsize=10, fontweight='bold')
ax1.set_ylabel('Y values', fontsize=10, fontweight='bold')
# Plot 2
ax2.loglog(PLOT2['X'], PLOT2['Y'], 'o',
markerfacecolor='blue', markeredgecolor='blue', markeredgewidth=1,
markersize=1.5, alpha=0.2)
ax2.set(xlim=(1e-4, 1e4), ylim=(1e-8, 1e2))
ax2.xaxis.set_major_locator(matplotlib.ticker.LogLocator(base=10.0, numticks=25))
ax2.yaxis.set_major_locator(matplotlib.ticker.LogLocator(base=10.0, numticks=25))
locmaj = matplotlib.ticker.LogLocator(base=10,numticks=25)
ax2.xaxis.set_major_locator(locmaj)
ax2.yaxis.set_major_locator(locmaj)
locmin = matplotlib.ticker.LogLocator(base=10.0,subs=(0.2,0.4,0.6,0.8),numticks=25)
ax2.xaxis.set_minor_locator(locmin)
ax2.yaxis.set_minor_locator(locmin)
ax2.xaxis.set_minor_formatter(matplotlib.ticker.NullFormatter())
ax2.yaxis.set_minor_formatter(matplotlib.ticker.NullFormatter())
ax2.set_xlabel('X values', fontsize=10, fontweight='bold')
ax2.set_ylabel('Y values', fontsize=10, fontweight='bold')
ax2.minorticks_on()
plt.show()
The plot I get is the following. As you can see, the minor ticks only appear on the x-axis from ax1.
How can I set the minor ticks in both subplots and both axis (x and y)?
Thank you so much.

Pyplot and Seaborn - How to add markers to the legend when they were produced by a seaborn plot

I am plotting 5 sets of data onto a single graph. For each set of data, I need to plot the scatter graph of the points (which I do using seaborn.regplot) and a line function which was separately fitted to the points.
The problem is that I can add the lines to the legend, but I can't add the markers from the regplot since I don't have any object handle on it. Here is my code:
f, ax = plt.subplots()
#Plotting the scatter points onto the axes object ax
sns.regplot(x='logF', y='R', data=MeanParams[(0 < MeanParams.M) & (0.2 > MeanParams.M)],
fit_reg=False, color='g', marker='+', ax=ax)
sns.regplot(x='logF', y='R', data=MeanParams[(0.2 < MeanParams.M) & (0.5 > MeanParams.M)],
fit_reg=False, color='y', marker='x', ax=ax)
sns.regplot(x='logF', y='R', data=MeanParams[(0.5 < MeanParams.M) & (1.5 > MeanParams.M)],
fit_reg=False, color='r', marker='x', ax=ax)
sns.regplot(x='logF', y='R', data=MeanParams[(1.5 < MeanParams.M) & (3.5 > MeanParams.M)],
fit_reg=False, color='b', marker='x', ax=ax)
sns.regplot(x='logF', y='R', data=MeanParams[(3.5 < MeanParams.M)],
fit_reg=False, color='k', marker='+', ax=ax)
#plotting the lines onto the same axes object
line1, = ax.plot(x, y_0, 'k-', linewidth=2)
line2, = ax.plot(x, y_1, 'k--', linewidth=2)
line3, = ax.plot(x, y_2, 'k-.', linewidth=3)
line4, = ax.plot(x, y_3, 'k:', linewidth=3)
line5, = ax.plot(x, y_4, 'r--', linewidth=2)
#creating the legend
ax.legend((line1,line2,line3,line4,line5),
(r'0.0 - 0.2', r'0.2 - 0.5', r'0.5 - 1.5', r'1.5 - 3.5', r'3.5 + '),
title='Mass Range', loc='upper left')
As you can see, I have handles on the line objects produced by ax.plot() but since I did the scatter plot with seaborn.regplot() I don't have any handle on the markers.
One easy way to solve this would be to persumably just use the pyplot scatter instead. But I guess I'm just asking out of curiosity, is there a way to pull out the line/marker objects so that I can put them into a legend as well?

How to create a legend in matplotlib

I am working on a regression problem and I want to plot 3 DataFrames. I don't know how to set the labels for the Dataframes. I want blue->ACTUAL, green->SVR, red->MLR.
What is wrong with the code?
ax1 = y_test[1800:1900].plot(color='blue', linewidth=3)
predicted_y[1800:1900].plot(color='green', linewidth=3, ax =ax1)
predicted_y1[1800:1900].plot(color='red', linewidth=3, ax=ax1)
plt.legend(loc='upper center', bbox_to_anchor=(0.5, 1.05), prop={'size':35})
plt.show()
I plot this and it shows me all colors with 0 values.
I think it should work if you add labels to your plots:
ax1 = y_test[1800:1900].plot(color='blue', linewidth=3, label = 'ACTUAL')
predicted_y[1800:1900].plot(color='green', linewidth=3, ax =ax1, label = 'SVR')
predicted_y1[1800:1900].plot(color='red', linewidth=3, ax=ax1, label = 'MVR')
plt.legend(loc='upper center', bbox_to_anchor=(0.5, 1.05), prop={'size':35})
plt.show()

Categories

Resources