Empty plot issue - python

As you can see in the picture attached when I execute my code I get two graphs and one of them is empty. I only need one so what is wrong with my code below?
kmf_par_modele = KaplanMeierFitter()
duration = iot_df_2.duree
observed = iot_df_2.batterie_0
fig, axes = plt.subplots(nrows = 1, ncols = 2, sharey = True, figsize=(12,15))
for modele_capteur, ax in zip(modele_capteur, axes.flatten()):
idx = iot_df_2.modele_objet == modele_capteur
kmf_par_modele.fit(duration[idx], observed[idx])
kmf_par_modele.plot(ax=ax, legend=False)
ax.annotate("Moyenne = {:.0f} mois".format(kmf_par_modele.median_), xy = (.47, .85), xycoords = "axes fraction")
ax.set_xlabel("")
ax.set_title(modele_capteur)
ax.set_xlim(0,25)
ax.set_ylim(0,1)
fig.tight_layout()
fig.text(0.5, -0.01, "Timeline (Mois)", ha="center")
fig.text(-0.01, 0.5, "Probabilité qu'un ERS_C02 ait toujours de la batterie", va="center", rotation="vertical")
fig.suptitle("Courbe de longévité pour le capteur ERS_C02",
fontsize=20)
fig.subplots_adjust(top=0.92)
plt.show()

As I mentioned in my comments, you just need to specify one single plot (subplot) if you only need one. I am answering because you don't need to flatten your axes instance because you just use a single figure. Here is how you can do it alternatively:
fig = plt.figure(figsize=(12,15))
ax = fig.add_subplot(111) # 111 means 1 row, 1 column ad 1st subplot (here only 1)
for modele_capteur in modele_capteur: # just loop over your modele_capteur
idx = iot_df_2.modele_objet == modele_capteur
kmf_par_modele.fit(duration[idx], observed[idx])
kmf_par_modele.plot(ax=ax, legend=False)
ax.annotate("Moyenne = {:.0f} mois".format(kmf_par_modele.median_), xy = (.47, .85), xycoords = "axes fraction")
ax.set_xlabel("")
ax.set_title(modele_capteur)
ax.set_xlim(0,25)
ax.set_ylim(0,1)

Related

saving figure in a loop matplotlib

I'm working on using a for loop to produce graphs for each set of data I have. Each plot prints correctly however the savefig() portion of my code only saves the last plot under each file name.
Here is a section of my code
total = 3
idx_list = []
dct = {}
for i, df in enumerate(graph_list):
data = pd.DataFrame(df)
for idx, v in enumerate(data['content'].unique()):
dct[f'x{idx}'] = data.loc[data['content'] == v]
idx_list.append(idx)
xs = dct[f'x{idx}'].Time
yB = dct[f'x{idx}'].Weight
yA = dct[f'x{idx}'].Height
fig, ax = plt.subplots(figsize =(10,8))
legends = ['Weight', 'Height']
ax.plot(xs, yB, linestyle = ':', color ='#4c4c4c', linewidth = 4.0)
ax.plot(xs, yA, color = '#fac346', linewidth = 3.0)
ax.legend(legends, loc = 'lower center', ncol = len(legends), bbox_to_anchor = (0.5, -0.15), frameon = False)
ax.yaxis.set_major_formatter(mtick.PercentFormatter(xmax=1, decimals = None, symbol ='%', is_latex = False))
ax.set_xticks(xs[::4])
ax.tick_params(axis = 'x', labelrotation = 45, labelsize = 10)
ax.yaxis.grid()
new_idx = [x+1 for x in idx_list]
for graph in range(total+1):
if graph != 0:
for ids in set(new_idx):
print('Graph {0} ID {1}'.format(graph, ids))
fig.savefig('Graph {0} ID {1}.jpg'.format(graph, ids))
I want each graph to save under the file names:
Graph 1 ID 1
Graph 1 ID 2
Graph 2 ID 1
Graph 2 ID 2
Graph 3 ID 1
Graph 3 ID 2
Thanks for any help you can provide!
You do not keep a reference to each figure, so when you call fig.savefig in the final loop you are actually saving the figure referenced by fig (which is the last figure) each time. There are many ways to manage this: you can save the figure in the same loop that created it, you can assign a unique name to each figure, or you can keep a reference to each figure in a list. The first option is simpler:
dct = {} # I assume this dict is used for something after saving the figures. Otherwise it is not necessary
for i, df in enumerate(graph_list):
data = pd.DataFrame(df)
for idx, v in enumerate(data['content'].unique()):
dct[f'x{idx}'] = data.loc[data['content'] == v]
xs = dct[f'x{idx}'].Time
yB = dct[f'x{idx}'].Weight
yA = dct[f'x{idx}'].Height
fig, ax = plt.subplots(figsize=(10, 8))
legends = ['Weight', 'Height']
ax.plot(xs, yB, linestyle=':', color='#4c4c4c', linewidth=4.0)
ax.plot(xs, yA, color='#fac346', linewidth=3.0)
ax.legend(legends, loc='lower center', ncol=len(legends),
bbox_to_anchor=(0.5, -0.15), frameon=False)
ax.yaxis.set_major_formatter(mtick.PercentFormatter(xmax=1,
decimals=None, symbol='%', is_latex=False))
ax.set_xticks(xs[::4])
ax.tick_params(axis='x', labelrotation=45, labelsize=10)
ax.yaxis.grid()
print('Graph {0} ID {1}'.format(i+1, idx+1))
fig.savefig('Graph {0} ID {1}.jpg'.format(i+1, idx+1))
plt.close(fig) # if you do not need to leave the figures open

Add a Right Yticks To a Plot

I am trying to make a plot of sort, this is my code and the output:
ticks = [3500, 5000]
labels = ["\u0332P", "P\u0305"]
plt.title("Nilai Premi Optimal \n dengan Batasan")
plt.xlabel("$\it{Bargaining Power}$ \u03BB")
plt.plot(xlamda, PsiBLamda, color = "red",linestyle='dashed',label = "$\u03C8_{B} (I^*(X))$")
plt.plot(xlamda, PsiSLamda, color = "blue",linestyle='dashed', label = "$\u03C8_{S} (I^*(X))$")
plt.legend(loc="upper left")
plt.plot(xlamda, PLamda, color = "black")
plt.xlim([0, 1])
plt.ylim([3500, 7000])
plt.show()
The plot output is correct, however I want to add a tick on the right y axis at the 5000 point with the label P. Here is an example:
How do I code that? Thank you
Check out secondary axes:
ticks = [3500, 5000]
labels = ["\u0332P", "P\u0305"]
fig, ax = plt.subplots() # need the axis object
plt.title("Nilai Premi Optimal \n dengan Batasan")
plt.xlabel("$\it{Bargaining Power}$ \u03BB")
plt.plot(xlamda, PsiBLamda, color = "red",linestyle='dashed',label = "$\u03C8_{B} (I^*(X))$")
plt.plot(xlamda, PsiSLamda, color = "blue",linestyle='dashed', label = "$\u03C8_{S} (I^*(X))$")
plt.legend(loc="upper left")
plt.plot(xlamda, PLamda, color = "black")
plt.xlim([0, 1])
plt.ylim([3500, 7000])
rightax = ax.secondary_yaxis('right') # create secondary axis on the right
rightax.set_yticks(ticks) # set tick locations
rightax.set_yticklabels(labels) # set tick labels
plt.show()

Visualizations are getting duplicated when using ipywidgets in Python jupyter notebooks

This is the code that I am using to output a drop down and a visualization. However with the drop down the visualization duplicates when I select a value.
def common_filtering(year):
output.clear_output()
plot_output.clear_output()
common_filter = Top_Team(year)
with output:
display(common_filter)
with plot_output:
plt.ioff
test = common_filter.player_name.tolist()
x = [10,35,30,30,35,65,65,65,100,95,95]
y = [40,10,30,50,70,20,40,60,40,60,20]
plt.style.use('ggplot')
pitch = Pitch(pitch_type='statsbomb', orientation='vertical',
pitch_color='#22312b', line_color='#c7d5cc', figsize=(16, 20),
constrained_layout=True, tight_layout=False,axis = True,label = True)
fig, ax = pitch.draw()
sc = pitch.scatter(x, y,
color ='red',edgecolors = 'black',
s=40000, ax=ax)
for i,j,k in zip(x,y,test):
pitch.annotate(k, (i,j),c='white', va='top', ha='center', size=16, weight='bold', ax=ax)
fig.set_facecolor("#22312b")
display(fig)
def dropdown_year_eventhandler(change):
common_filtering(change.new)
dropdown_year.observe(
dropdown_year_eventhandler, names='value')
display(dropdown_year) -- This is where the drop down is seen and underneath the duplicated visualizations
This is where essentially the output should be coming from and it is.
display(plot_output)
display(output)

Set size of matplotlib subplots

I created two subplots on a MPL figure, but i'm having an hard time setting the size on them. I want the space to be splitted between the two charts, so each chart needs to have 50% of the total width of the figure, and i want them to have the same height of the figure, here is how i initialized the subplots:
fig = plt.figure(facecolor='#131722',dpi=155, figsize=(10, 3))
ax1 = plt.subplot2grid((3,3), (2,0), facecolor='#131722')
ax2 = plt.subplot2grid((5,3), (2,2), colspan=5, rowspan=4, facecolor='#131722')
Colors = [['#0400ff', '#FF0000'], ['#09ff00', '#ff8c00']]
for x in List:
Index = List.index(x)
rate_buy = []
total_buy = []
rate_sell = []
total_sell = []
for y in x['data']['asks']:
rate_sell.append(y[0])
total_sell.append(y[1])
for y in x['data']['bids']:
rate_buy.append(y[0])
total_buy.append(y[1])
rBuys = pd.DataFrame({'buy': rate_buy})
rSells = pd.DataFrame({'sell': rate_sell})
tBuys = pd.DataFrame({'total': total_buy})
tSells = pd.DataFrame({'total': total_sell})
ax1.plot(rBuys.buy, tBuys.total, color=Colors[Index][0], linewidth=0.5, alpha=1, label='test')
ax2.plot(rSells.sell, tSells.total, color=Colors[Index][1],alpha=0.5, linewidth=1, label=x['exchange'])
ax1.fill_between(rBuys.buy, 0, tBuys.total, facecolor=Colors[Index][0], alpha=0.4)
ax2.fill_between(rSells.sell, 0, tSells.total, facecolor=Colors[Index][1], alpha=0.4)
And this is what i'm getting:
use plt.tight_layout() before calling plt.show().

Does anyone know how to get rid of the black 'y' axis to the left in Matplotlib plot?

After moving all of my 'y' axes to subplots I get an unwanted axis. It's the black one on the left. Does anyone know how to get rid of it? I'm sure it's getting plotted when I call the figure, however I'm not sure how to get rid of it.
def mpl_plot(self, plot_page, replot = 0): #Data stored in lists
if plot_page == 1: #Plot 1st Page
#plt0 = self.mplwidget.axes
fig = self.mplwidget.figure #Add a figure
if plot_page == 2: #Plot 2nd Page
#plt0 = self.mplwidget_2.axes
fig = self.mplwidget_2.figure #Add a figure
if plot_page == 3: #Plot 3rd Page
#plt0 = self.mplwidget_3.axes
fig = self.mplwidget_3.figure #Add a figure
#Clears Figure if data is roplotted
if replot == 1:
fig.clf()
par0 = fig.add_subplot(111)
par1 = fig.add_subplot(111)
par2 = fig.add_subplot(111)
#Add Axes
plt = par0.twinx()
ax1 = par1.twinx()
ax2 = par2.twinx()
impeller = str(self.comboBox_impellers.currentText()) #Get Impeller
fac_curves = self.mpl_factory_specs(impeller)
fac_lift = fac_curves[0]
fac_power = fac_curves[1]
fac_flow = fac_curves[2]
fac_eff = fac_curves[3]
fac_max_eff = fac_curves[4]
fac_max_eff_bpd = fac_curves[5]
fac_ranges = self.mpl_factory_ranges()
min_range = fac_ranges[0]
max_range = fac_ranges[1]
#Plot Chart
plt.hold(True)
plt.plot(fac_flow, fac_lift, 'b', linestyle = "dashed", linewidth = 1)
ax1.plot(fac_flow, fac_power, 'r', linestyle = "dashed", linewidth = 1)
ax2.plot(fac_flow, fac_eff, 'g', linestyle = "dashed", linewidth = 1)
#Move spines
ax2.spines["right"].set_position(("outward", 25))
self.make_patch_spines_invisible(ax2)
ax2.spines["right"].set_visible(True)
#Plot x axis minor tick marks
minorLocatorx = AutoMinorLocator()
ax1.xaxis.set_minor_locator(minorLocatorx)
ax1.tick_params(which='both', width= 0.5)
ax1.tick_params(which='major', length=7)
ax1.tick_params(which='minor', length=4, color='k')
#Plot y axis minor tick marks
minorLocatory = AutoMinorLocator()
plt.yaxis.set_minor_locator(minorLocatory)
plt.tick_params(which='both', width= 0.5)
plt.tick_params(which='major', length=7)
plt.tick_params(which='minor', length=4, color='k')
#Make Border of Chart White
fig.set_facecolor('white')
#Plot Grid
plt.grid(b=True, which='both', color='k', linestyle='-')
#set shaded Area
plt.axvspan(min_range, max_range, facecolor='#9BE2FA', alpha=0.5) #Yellow rectangular shaded area
#Set Vertical Lines
plt.axvline(fac_max_eff_bpd, color = '#69767A')
#BEP MARKER *** Can change marker style if needed
bep = fac_max_eff * 0.90 #bep is 90% of maximum efficiency point
bep_corrected = bep * 0.90 # We knock off another 10% to place the arrow correctly on chart
ax2.annotate('BEP', xy=(fac_max_eff_bpd, bep_corrected), xycoords='data', #Subtract 2.5 shows up correctly on chart
xytext=(-50, 30), textcoords='offset points',
bbox=dict(boxstyle="round", fc="0.8"),
arrowprops=dict(arrowstyle="-|>",
shrinkA=0, shrinkB=10,
connectionstyle="angle,angleA=0,angleB=90,rad=10"),
)
#Set Scales
plt.set_ylim(0,max(fac_lift) + (max(fac_lift) * 0.40)) #Pressure
#plt.set_xlim(0,max(fac_flow))
ax1.set_ylim(0,max(fac_power) + (max(fac_power) * 0.40)) #Power
ax2.set_ylim(0,max(fac_eff) + (max(fac_eff) * 0.40)) #Effiency
plt.yaxis.tick_left()
# Set Axes Colors
plt.tick_params(axis='y', colors='b')
ax1.tick_params(axis='y', colors='r')
ax2.tick_params(axis='y', colors='g')
# Set Chart Labels
plt.yaxis.set_label_position("left")
plt.set_xlabel("BPD")
plt.set_ylabel("Feet" , color = 'b')
#ax1.set_ylabel("BHP", color = 'r')
#ax1.set_ylabel("Effiency", color = 'g')
# Set tight layout
fig.set_tight_layout
# Since we moved Feet Axis to subplot, extra unneeded axis was created. This Removes it
# Refresh
fig.canvas.update()
fig.canvas.draw()
Well it looks like you have three y-axes, referencing the one you want to not be shown, you could try adding:
ax.yaxis.set_tick_params(labelsize=0, length=0, which='major')
to just make invisible the labels and ticks. I think it's ax2 you want gone?

Categories