Put legend for all lines on the matplolit - python

I'm running this code to plot a graph with two-axis but I'm getting an issue to display the legend for each line plotted on for the lines for the "first axis".
#create some mark data
temp=weather.head(4)
temp.set_index('Month', inplace=True)
temp=temp.transpose()
temp_label=list(ppt.head(0))
#display(ppt)
ppt=weather.tail(1)
ppt.set_index('Month', inplace=True)
ppt=ppt.transpose()
#display(temp)
fig, ax1 = plt.subplots()
color='tab:red'
ax1.set_ylabel('Temperature', color=color)
ax1.plot(temp.index, temp.loc[:,:], label=['A','B','C','D'])
ax1.tick_params(axis='y', labelcolor=color)
leg = ax1.legend(loc='upper left', fancybox=True, shadow=True)
leg.get_frame().set_alpha(0.4)
ax2 = ax1.twinx()
color = 'tab:grey'
ax2.set_ylabel('Precipitation (mm)', color='grey')
ax2.plot(ppt.index, ppt.loc[:,:], color='grey')
ax2.tick_params(axis='y', labelcolor='grey')
leg = ax2.legend(loc='upper right', fancybox=True, shadow=False)
leg.get_frame().set_alpha(0.4)
fig.tight_layout()
plt.show()

Try:
temp.plot(ax=ax1)
instead of
ax1.plot(temp.index, temp.loc[:,:], label=['A','B','C','D'])

Related

The following is my matplotlib but i think there's something wrong in it

fig=plt.figure()
ax1=fig.add_axes([0,0,1,1])
ax2=fig.add_axes([0.2,0.5,0.4,0.4])
ax1.set_xlim([0,100])
ax1.set_ylim([0,10000])
ax2.set_xlim([20,22])
ax2.set_ylim([30,50])
ax1.set_ylabel('Z')
ax1.set_xlabel('X')
ax1.xaxis.set_major_locator(ticker.MultipleLocator(2000))
ax1.yaxis.set_major_locator(ticker.MultipleLocator(20))
ax2.set_ylabel('Y')
ax2.set_xlabel('X')
ax2.xaxis.set_major_locator(ticker.MultipleLocator(5))
ax2.yaxis.set_major_locator(ticker.MultipleLocator(0.5))
This is printing out the following plot.
Fixed tick locators, adjusted subplot positioning, organized code a bit, hid spines, added dashed y grid, increased tick label font sizes.
fig, ax1 = plt.subplots(figsize=(12,8))
ax2 = fig.add_axes([0.575,0.55,0.3,0.3])
ax1.set_xlim([0,100])
ax1.set_ylim([0,10000])
ax1.set_xlabel('X', fontweight='bold')
ax1.set_ylabel('Z', rotation=0, fontweight='bold')
ax1.xaxis.set_major_locator(ticker.MultipleLocator(20))
ax1.yaxis.set_major_locator(ticker.MultipleLocator(1000))
ax1.grid(axis='y', dashes=(8,3), color='gray', alpha=0.3)
ax2.set_xlim([20,22])
ax2.set_ylim([30,50])
ax2.set_xlabel('X', fontweight='bold')
ax2.set_ylabel('Y', rotation=0, fontweight='bold')
ax2.xaxis.set_major_locator(ticker.MultipleLocator(0.5))
ax2.yaxis.set_major_locator(ticker.MultipleLocator(5))
for ax in [ax1, ax2]:
[ax.spines[s].set_visible(False) for s in ['top','right']]
ax.tick_params(axis='both', labelsize=12, left=False, bottom=False)

Adjusting legend layout for multiple legends associated to one Python plot?

I am creating a Python plot from a dataframe with 3 y-axes. For each y-axis, there are multiple y-values I want to plot. All data sets for the y-axes are plotted against a shared Date x-axis.
The code looks as follows:
df = pd.read_excel (r'test.xlsx', sheet_name='test', engine='openpyxl')
fig, ax = plt.subplots()
ax3 = ax.twinx()
rspine = ax3.spines['right']
rspine.set_position(('axes', 1.15))
ax3.set_frame_on(True)
ax3.patch.set_visible(False)
fig.subplots_adjust(right=0.7)
ax.plot(df['Date'], df['Gas1'], label="Gas1", color='g')
ax.plot(df['Date'], df['Gas2'], label="Gas2", color='b')
ax.plot(df['Date'], df['Gas3'], label="Gas3", marker="o", markersize=2, color='r')
ax.set_xlabel("Date")
ax.set_ylabel("Gas Rate")
ax2 = ax.twinx()
ax2.plot(df['Date'], df['Water1'], label="Water1", color='k')
ax2.plot(df['Date'], df['Water2'], label="Water2", color='y')
ax2.set_ylabel("Water")
ax3.plot(df['Date'], df['Pressure1'], label="Pressure1")
ax3.plot(df['Date'], df['Pressure2'], label="Pressure2")
ax3.set_ylabel("Pressure")
ax.legend()
ax2.legend()
ax3.legend()
plt.show()
The problem I am having is that I want the legends to be outside of the plot, preferably on the right-hand side after the 2nd y-axis. Is this possible? Right now the legends are just overlayed on the plot and not fully visible. I have tried using bbox_to_anchor and loc functions but had no luck. Thank you!
ax.get_legend_handles_labels() collects all the legend handles and their labels. Combining those for each of the axes, a new legend can be created.
bbox_to_anchor= sets an anchor point for the legend, using axes coordinates. loc= needs to be set, to tell which point of the legend's box will get fixed by the anchor.
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
df = pd.DataFrame({'Date': pd.date_range('20210401', periods=30, freq='D'),
'Gas1': np.random.randn(30).cumsum(),
'Gas2': np.random.randn(30).cumsum(),
'Gas3': np.random.randn(30).cumsum(),
'Water1': np.random.randn(30).cumsum(),
'Water2': np.random.randn(30).cumsum(),
'Pressure1': np.random.randn(30).cumsum(),
'Pressure2': np.random.randn(30).cumsum()})
fig, ax = plt.subplots()
ax3 = ax.twinx()
rspine = ax3.spines['right']
rspine.set_position(('axes', 1.15))
ax3.set_frame_on(True)
ax3.patch.set_visible(False)
fig.subplots_adjust(right=0.7)
ax.plot(df['Date'], df['Gas1'], label="Gas1", color='g')
ax.plot(df['Date'], df['Gas2'], label="Gas2", color='b')
ax.plot(df['Date'], df['Gas3'], label="Gas3", marker="o", markersize=2, color='r')
ax.set_ylabel("Gas Rate")
plt.setp(ax.get_xticklabels(), rotation=45, ha='right')
ax2 = ax.twinx()
ax2.plot(df['Date'], df['Water1'], label="Water1", color='k')
ax2.plot(df['Date'], df['Water2'], label="Water2", color='y')
ax2.set_ylabel("Water")
ax3.plot(df['Date'], df['Pressure1'], label="Pressure1")
ax3.plot(df['Date'], df['Pressure2'], label="Pressure2")
ax3.set_ylabel("Pressure")
handles1, labels1 = ax.get_legend_handles_labels()
handles2, labels2 = ax2.get_legend_handles_labels()
handles3, labels3 = ax3.get_legend_handles_labels()
ax.legend(handles=handles1 + handles2 + handles3,
labels=labels1 + labels2 + labels3,
bbox_to_anchor=(1.28, 1.02), loc='upper left')
plt.tight_layout()
plt.show()

How to make spines in matplotlib figure visible?

I would like to make the spines in my matplotlib figure visible, but they are not showing up.
fig, ax1 = plt.subplots(figsize=(10,6))
ax1.set_title(title+' vs Delinquency', fontsize=20, fontweight='bold')
ax1.set_facecolor('none')
ax1.spines['bottom'].set_color('black')
ax1.spines['left'].set_color('black')
ax1.spines['right'].set_color('black')
ax1=sns.barplot(x=feature, y='proportion', data=data, color='midnightblue')
plt.xticks(rotation=45, fontsize=12)
plt.yticks(fontsize=12)
plt.xlabel(title+' Group', fontsize=16)
plt.ylabel('Proportion', fontsize=16, color='midnightblue')
ax2=ax1.twinx()
ax2=sns.lineplot(x=feature, y='default_rate', data=data, color='firebrick')
plt.yticks(fontsize=12)
plt.ylabel('Default Rate', fontsize=16, color='firebrick')
plt.grid(None)
plt.show()

Python: Suplots with secondary-axis

I wrote the following code below to do the following graph:
fig, ax = plt.subplots(figsize=(8, 6))
ax.patch.set_facecolor('white')
ax.plot(df.index, df.X1.values, 'b',
label='NMA', linewidth=1.5)
ax.set_ylabel('Index')
ax2 = ax.twinx()
ax2.plot(df.index, df.Y.values, 'r--',
label='Rate', linewidth=1.5)
ax2.set_ylabel('Rate')
lines = ax.get_lines() + ax2.get_lines()
lgd = ax.legend(lines, [line.get_label() for line in lines],
loc='lower center', ncol=2, bbox_to_anchor=(0.5, -0.15),
frameon=False)
ax.set_title('Economic Rate and Index',
weight='bold')
for i in range(5):
plt.axvspan(Dates['Peak'][i], Dates['Trough'][i],
facecolor='grey', alpha=0.5)
plt.grid(False)
plt.savefig('C:\\test.pdf',
bbox_extra_artists=(lgd,), bbox_inches='tight')
I am having a hard time to reproduce this figure in a subplot (2X2). The only thing I would change in each of the subplots is the blue line (X1 in df... for X2, X3...). How can I have a 2X2 subplot of the above graph? Of Course I would only keep one legend at the bottom of the subplots. Thanks for the help.
The data is here and the "Dates" to reproduce the gray bars here.
This is how you could create a 2x2 raster with twinx each:
import matplotlib.pyplot as plt
fig, ((ax1a, ax2a), (ax3a, ax4a)) = plt.subplots(2, 2)
ax1b = ax1a.twinx()
ax2b = ax2a.twinx()
ax3b = ax3a.twinx()
ax4b = ax4a.twinx()
ax1a.set_ylabel('ax1a')
ax2a.set_ylabel('ax2a')
ax3a.set_ylabel('ax3a')
ax4a.set_ylabel('ax4a')
ax1b.set_ylabel('ax1b')
ax2b.set_ylabel('ax2b')
ax3b.set_ylabel('ax3b')
ax4b.set_ylabel('ax4b')
plt.tight_layout()
plt.show()
Result:

Matplotlib plot disappears after annotating?

fig1 = figure()
ax = fig1.add_subplot(111, autoscale_on = False)
ax.plot(data[:,0]*1E6, data[:,3]
,data[:,0]*1E6, data[:,4],'r')
plt.xlabel('Time (us)')
plt.ylabel('Voltage (V)')
plt.title('Time')
plt.grid()
ax.annotate('axes center', xy=(.5, .5), xycoords='axes fraction',
horizontalalignment='center', verticalalignment='center')
plt.gca().xaxis.set_major_locator(MaxNLocator(prune='lower'))
plt.savefig('Time.png',orientation='landscape', pad_inches=0.1)
plt.clf()
The plot disappears after annotating. Only thing that is left after saving is the annotation. Can someone give a suggestion how to save it after annotating.

Categories