ম্যাটপ্লটলিব টাইট_এলআউট () অ্যাকাউন্ট ফিগার স্যুটিটল গ্রহণ করে না


207

যদি আমি আমার ম্যাটপ্ল্লিটিব ফিগারে একটি সাবটাইটেল যুক্ত করি তবে এটি সাবপ্লট এর শিরোনাম দ্বারা আবৃত হয়ে যায়। কেউ কীভাবে সহজেই তার যত্ন নিতে জানেন? আমি tight_layout()ফাংশনটি চেষ্টা করেছিলাম , তবে এটি কেবল জিনিসগুলিকে আরও খারাপ করে।

উদাহরণ:

import numpy as np
import matplotlib.pyplot as plt

f = np.random.random(100)
g = np.random.random(100)
fig = plt.figure()
fig.suptitle('Long Suptitle', fontsize=24)
plt.subplot(121)
plt.plot(f)
plt.title('Very Long Title 1', fontsize=20)
plt.subplot(122)
plt.plot(g)
plt.title('Very Long Title 2', fontsize=20)
plt.tight_layout()
plt.show()

উত্তর:


178

আপনি নীচে খুব tight_layoutকলটিতে সাবপ্লট জ্যামিতি সামঞ্জস্য করতে পারেন :

fig.tight_layout(rect=[0, 0.03, 1, 0.95])

যেমনটি ডকুমেন্টেশনে বলা হয়েছে ( https://matplotlib.org/users/tight_layout_guide.html ):

tight_layout()কেবল টিক্লেবেলস, অক্ষ লেবেল এবং শিরোনাম বিবেচনা করে। সুতরাং, অন্যান্য শিল্পীরা ক্লিপড হয়ে যেতে পারে এবং ওভারল্যাপও করতে পারে।


1
এটি কবজির মতো কাজ করেছে, তবে বাউন্ডিং বক্স নির্দিষ্ট করার সাথে কীভাবে পরিবর্তন ঘটে? আমি ডকটি পড়েছি তবে আমার কাছে খুব বেশি পরিষ্কার ছিল না। আপনি দয়া করে আমাকে ব্যাখ্যা করতে পারলে এটি দুর্দান্ত হবে! ধন্যবাদ।
thepunitsingh

2
আপনি কি অনুগ্রহপূর্বক প্রতিটি সংখ্যার অর্থ ব্যাখ্যা করতে পারেন? আমি তাদের দস্তাবেজে দেখিনি।
স্টিভেন

6
@ স্টেভেন tight_layoutডক্স দেখুন:[left, bottom, right, top] in normalized (0, 1) figure coordinates
স্যুপল্ট

1
আপনি যথাক্রমে এবং অক্ষগুলির মধ্যে স্থানটি আরও ন্যূনতম মানকে কমিয়ে আরও বাড়িয়ে তুলতে পারেন: tight_layout(rect=[0, 0.03, 1, 0.9])পরিবর্তে 0.95উত্তরের পরিবর্তে ।
কমফ্রিচ

1
জুপিটারের ভিতরে কাজ করেনি। সংখ্যার জন্য বিভিন্ন মানের চেষ্টা করা হয়েছে, এর কোনও প্রভাব ছিল না
আলেকসেজ ফমিনস

114

আপনি ম্যানুয়ালি এই ব্যবধানটি ব্যবহার করে সামঞ্জস্য করতে পারেন plt.subplots_adjust(top=0.85):

import numpy as np
import matplotlib.pyplot as plt

f = np.random.random(100)
g = np.random.random(100)
fig = plt.figure()
fig.suptitle('Long Suptitle', fontsize=24)
plt.subplot(121)
plt.plot(f)
plt.title('Very Long Title 1', fontsize=20)
plt.subplot(122)
plt.plot(g)
plt.title('Very Long Title 2', fontsize=20)
plt.subplots_adjust(top=0.85)
plt.show()

5
নোট করুন শীর্ষের জন্য ডিফল্ট মান 0.9 হয় যখন আপনি কল করবেনsubplots_adjust
ব্রায়ান বার্নস

72
আমি আমাদের প্রভুর ২০১৩ সালে বিশ্বাস করতে পারি না এটি এখনও ম্যাটপ্ল্লোলিবের একটি বাগ g
শব্দসুখে

29
লক্ষ্য করুন subplots_adjustকল করা আবশ্যক পর কোনো কল tight_layout, অথবা কলিং কোনো প্রভাব থাকবে subplots_adjust
আচল দাভে

7
@Wordferhewise এখনই এটি 2018 করুন
vlsd

6
@vlsd 2019 এর হ্যালো
জিয়াওউ লু

55

আপনি খুব সহজেই আপনার কোডটিতে পরিবর্তন করতে পারেন এমন একটি জিনিস আপনি fontsizeশিরোনামগুলির জন্য ব্যবহার করছেন। যাইহোক, আমি ধরে নিচ্ছি যে আপনি কেবল এটি করতে চান না!

ব্যবহারের কিছু বিকল্প fig.subplots_adjust(top=0.85):

সাধারণত tight_layout()ভাল অবস্থানে সমস্ত কিছুকে স্থিতি করতে খুব ভাল কাজ করে যাতে তারা ওভারল্যাপ না করে। কারণ tight_layout()না এই ক্ষেত্রে সাহায্যের কারণ নেই tight_layout()fig.suptitle () একাউন্টে নেয় না। গিটহাবে এটি সম্পর্কে একটি উন্মুক্ত সমস্যা রয়েছে: https://github.com/matplotlib/matplotlib/issues/829 [একটি পূর্ণ জ্যামিতি পরিচালক প্রয়োজনের কারণে 2014 সালে বন্ধ - https://github.com/matplotlib/matplotlib এ স্থানান্তরিত / ইস্যু / 1109 ]।

আপনি যদি থ্রেডটি পড়েন তবে জড়িত আপনার সমস্যার সমাধান রয়েছে GridSpec। মূলটি হ'ল কোয়ার্গ tight_layoutব্যবহার করে কল করার সময় চিত্রের শীর্ষে কিছু স্থান rectরেখে দেওয়া। আপনার সমস্যার জন্য, কোডটি হয়ে যায়:

গ্রিডস্পেক ব্যবহার করে

import numpy as np
import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec

f = np.random.random(100)
g = np.random.random(100)

fig = plt.figure(1)
gs1 = gridspec.GridSpec(1, 2)
ax_list = [fig.add_subplot(ss) for ss in gs1]

ax_list[0].plot(f)
ax_list[0].set_title('Very Long Title 1', fontsize=20)

ax_list[1].plot(g)
ax_list[1].set_title('Very Long Title 2', fontsize=20)

fig.suptitle('Long Suptitle', fontsize=24)    

gs1.tight_layout(fig, rect=[0, 0.03, 1, 0.95])  

plt.show()

ফলাফল:

গ্রিডস্পেক ব্যবহার করে

হতে পারে আপনার GridSpecজন্য কিছুটা ওভারকিল, বা আপনার আসল সমস্যাটি আরও অনেক বড় ক্যানভাসে বা অন্য জটিলতায় আরও অনেক সাবপ্লট জড়িত। একটি সাধারণ হ্যাক হ'ল এটিকে অনুকরণ annotate()করার জন্য স্থানাঙ্কগুলি ব্যবহার এবং লক 'figure fraction'করা suptitle। যদিও আউটপুটটি একবার দেখুন, আপনার কিছু সূক্ষ্ম সামঞ্জস্য করার প্রয়োজন হতে পারে। নোট করুন যে এই দ্বিতীয় সমাধানটি ব্যবহার করে নাtight_layout()

সহজ সমাধান (যদিও এটি সূক্ষ্ম সুরের প্রয়োজন হতে পারে)

fig = plt.figure(2)

ax1 = plt.subplot(121)
ax1.plot(f)
ax1.set_title('Very Long Title 1', fontsize=20)

ax2 = plt.subplot(122)
ax2.plot(g)
ax2.set_title('Very Long Title 2', fontsize=20)

# fig.suptitle('Long Suptitle', fontsize=24)
# Instead, do a hack by annotating the first axes with the desired 
# string and set the positioning to 'figure fraction'.
fig.get_axes()[0].annotate('Long Suptitle', (0.5, 0.95), 
                            xycoords='figure fraction', ha='center', 
                            fontsize=24
                            )
plt.show()

ফলাফল:

সহজ

[ Python২.7.৩ (64৪-বিট) এবং ১.২.০ ব্যবহার করে matplotlib]


1
ধন্যবাদ, আমি যদি আপনার প্রস্তাবিত প্রথম সমাধানটি ব্যবহার করি (ব্যবহার করে GridSpec) তবে আমি কীভাবে সাবস্কটগুলি তৈরি করতে পারি যাতে অক্ষগুলি ভাগ করে নেওয়া হয়? plt.subplots(N,1, sharex=<>, sharey=<>)সাবপ্লট তৈরি করার সময় আমি সাধারণত ব্যবহার করি তবে আপনি পোস্ট করা কোডটি add_subplotপরিবর্তে ব্যবহার করে
আমেলিও ওয়াজকেজ-রেইনা

10
কাস্টিংও fig.tight_layout(rect=[0, 0.03, 1, 0.95])কাজ করে।
স্যুপোল্ট

1
দ্বিতীয় সমাধানটি কেবল আমার পক্ষে কাজ করেছিল that ধন্যবাদ!
হ্যাগবার্ড

19

সমাধানের সমাধানের জন্য বিকল্প এবং সহজ হ'ল উপসর্গটির ডাকে y টি যুক্তি ব্যবহার করে চিত্রের উপগ্রহ পাঠ্যের স্থানাঙ্কগুলি সামঞ্জস্য করা ( দস্তাবেজগুলি দেখুন ):

import numpy as np
import matplotlib.pyplot as plt

f = np.random.random(100)
g = np.random.random(100)
fig = plt.figure()
fig.suptitle('Long Suptitle', y=1.05, fontsize=24)
plt.subplot(121)
plt.plot(f)
plt.title('Very Long Title 1', fontsize=20)
plt.subplot(122)
plt.plot(g)
plt.title('Very Long Title 2', fontsize=20)
plt.show()

8
এটি একটি নোটবুকে দুর্দান্ত উপায় তবে plt.savefig () কমান্ড মানছে না। এই সমাধানটি এখনও একটি সেফফিগ কমান্ডে শিরোনামটি কেটে দেয়।
সুপারহিরো

11

আঁটসাঁট লেআউটটি সাবটাইটেলের সাথে কাজ করে না, তবে constrained_layoutতা করে। এই প্রশ্নটি দেখুন ম্যাটপ্ল্লোব-এ অনেক সাবপ্লট দিয়ে সাবপ্লট আকার / ব্যবধান উন্নত করুন

আমি সাব-প্লটগুলি একবারে আরও ভাল দেখতে দেখতে পেলাম, যেমন

fig, axs = plt.subplots(rows, cols, constrained_layout=True)

# then iterating over the axes to fill in the plots

তবে চিত্রটি তৈরি হওয়ার পরে এটি যুক্ত করা যেতে পারে:

fig = plt.figure(constrained_layout=True)

ax1 = fig.add_subplot(cols, rows, 1)
# etc

দ্রষ্টব্য: আমার সাবপ্লটগুলি একসাথে আরও ঘনিষ্ঠ করতে, আমিও ব্যবহার করছিলাম

fig.subplots_adjust(wspace=0.05)

এবং সীমাবদ্ধ_আউটআউট এর সাথে কাজ করে না :(


4

আমি matplotlib পদ্ধতি ছাঁটাই সঙ্গে লড়াই করেছেন তাই আমি এখন শুধু একটি মাধ্যমে এই কাজ করতে একটি ফাংশন তৈরি করেছি bashথেকে কল ImageMagickএর mogrify কমান্ড , যা ভাল কাজ করে এবং চিত্র এর প্রান্ত বন্ধ সব অতিরিক্ত সাদা স্থান পায়। এটির জন্য আপনি ইউএনআইএক্স / লিনাক্স ব্যবহার করছেন, bashশেলটি ব্যবহার করছেন এবং ImageMagickইনস্টল করেছেন requires

আপনার savefig()কল করার পরে এইটিতে কেবল একটি কল নিক্ষেপ করুন।

def autocrop_img(filename):
    '''Call ImageMagick mogrify from bash to autocrop image'''
    import subprocess
    import os

    cwd, img_name = os.path.split(filename)

    bashcmd = 'mogrify -trim %s' % img_name
    process = subprocess.Popen(bashcmd.split(), stdout=subprocess.PIPE, cwd=cwd)

3

অন্যদের দ্বারা উল্লিখিত হিসাবে, ডিফল্টভাবে আঁটসাঁট লেআউটটি সাবটাইটেলটিকে বিবেচনায় নেয় না। যাইহোক, আমি খুঁজে পেয়েছি bbox_extra_artistsযে সাবটাইটলে একটি বাউন্ডিং বাক্স হিসাবে বিবেচনায় নেওয়া উচিত হিসাবে পাস করার জন্য যুক্তিটি ব্যবহার করা সম্ভব :

st = fig.suptitle("My Super Title")
plt.savefig("figure.png", bbox_extra_artists=[st], bbox_inches='tight')

এই আঁটসাঁট লেআউট গণনাটিকে আমলে নিতে suptitleজোর করে, এবং এটি আপনার প্রত্যাশা মতো দেখায়।


এটি আমার পক্ষে কাজ করা একমাত্র বিকল্প। আমি অঙ্কগুলি তৈরি করতে এবং সেভ করতে জুপিটার নোটবুকগুলি ব্যবহার করি। আমি লিনাক্স মেশিনে পাইথন ৩.6 এ কাজ করি।
GRquanti

1

আমার একটি অনুরূপ সমস্যা ছিল যা tight_layoutখুব বড় গ্রিডের জন্য ব্যবহৃত হয়েছিল (200 এরও বেশি সাবপ্লট) এবং খুব বড় নোটবুকে রেন্ডারিংয়ের সময়। আমি একটি দ্রুত সমাধান তৈরি করেছি যা সর্বদা আপনাকে suptitleআপনার শীর্ষ সাবপ্লোটের উপরে একটি নির্দিষ্ট দূরত্বে রাখে:

import matplotlib.pyplot as plt

n_rows = 50
n_col = 4
fig, axs = plt.subplots(n_rows, n_cols)

#make plots ...

# define y position of suptitle to be ~20% of a row above the top row
y_title_pos = axs[0][0].get_position().get_points()[1][1]+(1/n_rows)*0.2
fig.suptitle('My Sup Title', y=y_title_pos)

ভেরিয়েবল-আকারের সাবপ্লটগুলির জন্য, আপনি এখনও শীর্ষস্থানীয় সাবপ্লটটির শীর্ষস্থান পেতে এই পদ্ধতিটি ব্যবহার করতে পারেন, তারপরে সাবটাইটলে যোগ করার জন্য ম্যানুয়ালি একটি অতিরিক্ত পরিমাণ নির্ধারণ করুন।


1

আমার জন্য কাজ করা একমাত্র জিনিসটি কলটিকে সাবটাইটেলে পরিবর্তন করছিল:

fig.suptitle("title", y=.995)
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.