অন্যান্য উত্তরের পদ্ধতিগুলি yticks বড় হলে সঠিকভাবে কাজ করবে না। ইয়েলবেল হয় টিক্স দিয়ে ওভারল্যাপ করবে, বামদিকে ক্লিপ হবে বা চিত্রের বাইরে সম্পূর্ণ অদৃশ্য হবে।
আমি হ্যাগেনের উত্তরটি পরিবর্তন করেছি তাই এটি xlabel এবং ইলাবেল উভয়ের জন্যই 1 টিরও বেশি সাবপ্লটগুলির কলামের সাথে কাজ করে এবং এটি চিত্রটিতে ইলাবেলকে দৃশ্যমান রাখার চক্রান্ত স্থানান্তরিত করে।
def set_shared_ylabel(a, xlabel, ylabel, labelpad = 0.01, figleftpad=0.05):
"""Set a y label shared by multiple axes
Parameters
----------
a: list of axes
ylabel: string
labelpad: float
Sets the padding between ticklabels and axis label"""
f = a[0,0].get_figure()
f.canvas.draw() #sets f.canvas.renderer needed below
# get the center position for all plots
top = a[0,0].get_position().y1
bottom = a[-1,-1].get_position().y0
# get the coordinates of the left side of the tick labels
x0 = 1
x1 = 1
for at_row in a:
at = at_row[0]
at.set_ylabel('') # just to make sure we don't and up with multiple labels
bboxes, _ = at.yaxis.get_ticklabel_extents(f.canvas.renderer)
bboxes = bboxes.inverse_transformed(f.transFigure)
xt = bboxes.x0
if xt < x0:
x0 = xt
x1 = bboxes.x1
tick_label_left = x0
# shrink plot on left to prevent ylabel clipping
# (x1 - tick_label_left) is the x coordinate of right end of tick label,
# basically how much padding is needed to fit tick labels in the figure
# figleftpad is additional padding to fit the ylabel
plt.subplots_adjust(left=(x1 - tick_label_left) + figleftpad)
# set position of label,
# note that (figleftpad-labelpad) refers to the middle of the ylabel
a[-1,-1].set_ylabel(ylabel)
a[-1,-1].yaxis.set_label_coords(figleftpad-labelpad,(bottom + top)/2, transform=f.transFigure)
# set xlabel
y0 = 1
for at in axes[-1]:
at.set_xlabel('') # just to make sure we don't and up with multiple labels
bboxes, _ = at.xaxis.get_ticklabel_extents(fig.canvas.renderer)
bboxes = bboxes.inverse_transformed(fig.transFigure)
yt = bboxes.y0
if yt < y0:
y0 = yt
tick_label_bottom = y0
axes[-1, -1].set_xlabel(xlabel)
axes[-1, -1].xaxis.set_label_coords((left + right) / 2, tick_label_bottom - labelpad, transform=fig.transFigure)
এটি নিম্নলিখিত উদাহরণের জন্য কাজ করে, যখন হাগেনের উত্তর ইয়েলবেল আঁকবে না (যেহেতু এটি ক্যানভাসের বাইরে) এবং কেওয়াইসির ইয়েলবেলটি টিক লেবেলগুলির সাথে ওভারল্যাপ করে:
import matplotlib.pyplot as plt
import itertools
fig, axes = plt.subplots(3, 4, sharey='row', sharex=True, squeeze=False)
fig.subplots_adjust(hspace=.5)
for i, a in enumerate(itertools.chain(*axes)):
a.plot([0,4**i], [0,4**i])
a.set_title(i)
set_shared_ylabel(axes, 'common X', 'common Y')
plt.show()
বিকল্পভাবে, আপনি বর্ণহীন অক্ষের সাথে ভাল থাকলে, আমি জুলিয়ান চেনের সমাধানটি পরিবর্তন করেছি যাতে ইয়াবেল টিক লেবেলগুলির সাথে ওভার্যাপল্যাপ না করে।
মূলত, আমাদের বর্ণহীন রঙের ইলিমস সেট করতে হবে তাই এটি সাবপ্লটগুলির বৃহত্তম ইলিমের সাথে মেলে যাতে বর্ণহীন টিক লেবেলগুলি ইলেবেলের সঠিক অবস্থান নির্ধারণ করে।
আবার, ক্লিপিং প্রতিরোধের জন্য আমাদের প্লটটি সঙ্কুচিত করতে হবে। এখানে আমি সঙ্কুচিত হওয়ার জন্য পরিমাণটি কঠোরভাবে কোড করেছি, তবে আপনি এমন কোনও নম্বর খুঁজে পেতে খেলতে পারেন যা আপনার পক্ষে কাজ করে বা উপরের পদ্ধতিতে এটি গণনা করতে পারে।
import matplotlib.pyplot as plt
import itertools
fig, axes = plt.subplots(3, 4, sharey='row', sharex=True, squeeze=False)
fig.subplots_adjust(hspace=.5)
miny = maxy = 0
for i, a in enumerate(itertools.chain(*axes)):
a.plot([0,4**i], [0,4**i])
a.set_title(i)
miny = min(miny, a.get_ylim()[0])
maxy = max(maxy, a.get_ylim()[1])
# add a big axes, hide frame
# set ylim to match the largest range of any subplot
ax_invis = fig.add_subplot(111, frameon=False)
ax_invis.set_ylim([miny, maxy])
# hide tick and tick label of the big axis
plt.tick_params(labelcolor='none', top=False, bottom=False, left=False, right=False)
plt.xlabel("common X")
plt.ylabel("common Y")
# shrink plot to prevent clipping
plt.subplots_adjust(left=0.15)
plt.show()