Add a Right Yticks To a Plot - python

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

Related

Seaborn Align twinx and x Axis

I am trying to align X axis with its twin but I'm not finding a way to do it.
Here is my code
# Initialize the figure
plt.figure(figsize=(16, 10))
# Adding a title
plt.title(f'Client Retention Quarters: Monthly Cohorts', fontsize = 14)
# Creating the heatmap
sns.heatmap(retention, annot = True,vmin = 0, vmax =30,cmap="flare", fmt='g')
plt.ylabel('Cohort Quarter')
plt.xlabel('')
plt.yticks( rotation='360')
#Twinx
ax2 = plt.twiny()
ax2.set_xticks(range(0,len(x2)))
ax2.set_xticklabels(labels=x2)
ax2.spines['top'].set_position(('axes', -0.10))
plt.show()
And here is the output:
I want to align the percentages with the x ticks.
Is it possible?
You can use the below updated code. See if this works. Note that I have used random data for retention and x2. Basically, the main change it to get the xlim()s for both axes and then adjust it (see lambda f) so that the ticks align. Finally use set_major_locator() to fix the points. Hope this is what you are looking for...
retention = np.random.rand(10, 12) ##My random data
# Initialize the figure
plt.figure(figsize=(16, 10))
# Adding a title
plt.title(f'Client Retention Quarters: Monthly Cohorts', fontsize = 14)
# Creating the heatmap
ax=sns.heatmap(retention, annot = True,vmin = 0, vmax =30,cmap="flare", fmt='g') ## Note I am assigning to ax
plt.ylabel('Cohort Quarter')
plt.xlabel('')
plt.yticks( rotation='360')
x2 = np.around(np.linspace(1, 25, 12),2)
#Twinx
ax2 = ax.twiny()
#ax2.set_xticks(range(0,len(x2))) ## Commented as not required
#ax2.set_xticklabels(labels=x2) ## Commented as not required
## New code here ##
import matplotlib.ticker
l = ax.get_xlim()
l2 = ax2.get_xlim()
f = lambda y : l2[0]+(y-l[0])/(l[1]-l[0])*(l2[1]-l2[0]) ##Add delta to each tick
ticks = f(ax.get_xticks())
ax2.xaxis.set_major_locator(matplotlib.ticker.FixedLocator(ticks)) ##Set the ticks
ax2.spines['top'].set_position(('axes', -0.10))
plt.show()

Matplotlib:Legend python with no show in the legend information, only a transparent square showed

x = range(11, 31)
y_1 = [1,0,1,1,2,4,3,2,3,4,4,5,6,5,4,3,3,1,1,1]
y_2 = [1,0,3,1,2,2,3,3,3,2,1,2,1,1,1,1,1,1,1,1]
# 图形大小
plt.figure(figsize=(20, 8), dpi = 80)
# 设置x轴刻度
x_label = ["{}岁".format(i) for i in x]
plt.xticks(list(x), x_label, fontproperties = my_font) # 显示中文刻度
# 绘制网格
plt.grid(alpha = 0.4)
# 添加图例
plt.legend(prop = my_font, loc = "upper left")
# Execution
plt.plot(x, y_1, label = "Mine")
plt.plot(x, y_2, label = "Him")
# Display
plt.show()
This is the code for legends showing in Python matplotlib, and I wanna show the legend, but the result is that there is no show at all.
You need to call plt.legend after plotting the curves:
# first
plt.plot(x, y_1, label = "Mine")
plt.plot(x, y_2, label = "Him")
# next
plt.legend(loc = "upper left")
output (smaller size):

Plot less points (line plot) for matplot lib

Currently I have a plot with too many points, I want to avoid overlapping. Want to know how to reduce the amount of points in order to have a smoother line.
Plot Code
fig = plt.figure(1, figsize = (18,10)) # Figure size in inches (size_x, size_y)
ax = plt.axes()
min_val = prediction_intervals2[:, 0]
max_val = prediction_intervals2[:, 1]
true_values = y_test
predicted_values = PLS_Model1.predict(X_test)
plt.plot(min_val, label = "Min", color='blue')
plt.plot(max_val, label = "Max", color='red')
plt.plot(true_values, label = "y", color = "black")
plt.plot(predicted_values, label = "y\u0302", marker='o')
plt.title('Conformal Predictor Final Predictions')
plt.legend()
plt.show()
Current Plot
Desired Plot
Plot that I want
I was able to revise my code properly and came to the desired output by just selecting less data points, quite simple. Posted the answer just in case.
min_val_normal = plot_normalized_table[['Min']]
max_val_normal = plot_normalized_table[['Max']]
original_normal = plot_normalized_table[['Original Label']]
interval_normal = plot_normalized_table[['Interval Size']]
normal_predicted = predicted_values[0:50]
fig = plt.figure(1, figsize = (18,10)) # Figure size in inches (size_x, size_y)
ax = plt.axes()
#predicted_values = PLS_Model1.predict(X_test) #Predictions from test data (run at least once for the plot to work)
plt.plot(min_val_normal, label = "Min", color='blue')
plt.plot(max_val_normal, label = "Max", color='red')
plt.plot(original_normal, label = "y", color = "black")
plt.plot(normal_predicted, label = "y\u0302", marker='o', )
plt.title('Normalized Final Conformal Predictions')
plt.xlim([-1, 51])
plt.ylim([-1, 2])
plt.legend()
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?

Why is there extra space at the bottom of this plot?

I just created a horizontal stacked bar chart using matplotlib, and I can't figure out why there is extra space between the x axis and the first bar (code and picture below). Any suggestions or questions? Thanks!
Code:
fig = figure(facecolor="white")
ax1 = fig.add_subplot(111, axisbg="white")
heights = .43
data = np.array([source['loan1'],source['loan2'],source['loan3']])
dat2 = np.array(source2)
ind=np.arange(N)
left = np.vstack((np.zeros((data.shape[1],), dtype=data.dtype), np.cumsum(data, axis=0) [:-1]))
colors = ( '#27A545', '#7D3CBD', '#C72121')
for dat, col, lefts, pname2 in zip(data, colors, left, pname):
ax1.barh(ind+(heights/2), dat, color=col, left=lefts, height = heights, align='center', alpha = .5)
p4 = ax1.barh(ind-(heights/2), dat2, height=heights, color = "#C6C6C6", align='center', alpha = .7)
ax1.spines['right'].set_visible(False)
ax1.yaxis.set_ticks_position('left')
ax1.spines['top'].set_visible(False)
ax1.xaxis.set_ticks_position('bottom')
yticks([z for z in range(N)], namelist)
#mostly for the legend
params = {'legend.fontsize': 8}
rcParams.update(params)
box = ax1.get_position()
ax1.set_position([box.x0, box.y0 + box.height * 0.1, box.width, box.height * 0.9])
l = ax1.legend(loc = 'upper center', bbox_to_anchor=(0.5,-0.05), fancybox=True, shadow = True, ncol = 4)
show()
This is because matplotlib tries to intelligently choose minimum and maximum limits for the plot (i.e. "round-ish" numbers) by default.
This makes a lot of sense for some plots, but not for others.
To disable it, just do ax.axis('tight') to snap the data limits to the strict extents of the data.
If you want a bit of padding despite the "tight" bounds on the axes limits, use ax.margins.
In your case, you'd probably want something like:
# 5% padding on the y-axis and none on the x-axis
ax.margins(0, 0.05)
# Snap to data limits (with padding specified above)
ax.axis('tight')
Also, if you want to set the extents manually, you can just do
ax.axis([xmin, xmax, ymin, ymax])`
or use set_xlim, set_ylim, or even
ax.set(xlim=[xmin, xmax], ylim=[ymin, ymax], title='blah', xlabel='etc')

Categories