অক্ষের বাইরে ম্যাটপ্লোটিলিব কিংবদন্তি স্থানান্তরিত করা এটি চিত্র চিত্র দ্বারা কাট অফ করে


222

আমি নিম্নলিখিত প্রশ্নের সাথে পরিচিত:

প্লটের বাইরে কিংবদন্তি সহ ম্যাটপ্লটলিব সেফফিগ

কীভাবে কিংবদন্তিটি প্লটের বাইরে রাখবেন

দেখে মনে হচ্ছে যে এই প্রশ্নের উত্তরগুলিতে অক্ষটি সংক্ষিপ্তভাবে সঙ্কুচিত হওয়ার সাথে মিলিয়ে উঠতে সক্ষম হওয়ার বিলাসিতা রয়েছে যাতে কিংবদন্তিটি ফিট হয়।

অক্ষগুলি সঙ্কুচিত করা কোনও আদর্শ সমাধান নয় কারণ এটি ডেটাটিকে আরও ছোট করে তোলে যার অর্থ ব্যাখ্যা করা আরও কঠিন হয়; বিশেষত যখন এর জটিল এবং সেখানে প্রচুর জিনিস চলছে ... সুতরাং একটি বিশাল কিংবদন্তির প্রয়োজন

ডকুমেন্টেশনে একটি জটিল কিংবদন্তির উদাহরণ এটির প্রয়োজনীয়তা প্রদর্শন করে কারণ তাদের চক্রান্তের কিংবদন্তি আসলে একাধিক ডেটা পয়েন্টকে পুরোপুরি অস্পষ্ট করে।

http://matplotlib.sourceforge.net/users/legend_guide.html#legend-of-complex-plots

আমি যেটি করতে সক্ষম হতে চাই তা হ'ল ডায়াগোনিকভাবে চিত্রের বাক্সের আকারকে প্রসারিত ফিগার কিংবদন্তির সাথে সামঞ্জস্য করতে expand

import matplotlib.pyplot as plt
import numpy as np

x = np.arange(-2*np.pi, 2*np.pi, 0.1)
fig = plt.figure(1)
ax = fig.add_subplot(111)
ax.plot(x, np.sin(x), label='Sine')
ax.plot(x, np.cos(x), label='Cosine')
ax.plot(x, np.arctan(x), label='Inverse tan')
lgd = ax.legend(loc=9, bbox_to_anchor=(0.5,0))
ax.grid('on')

লক্ষ্য করুন কীভাবে চূড়ান্ত লেবেল 'বিপরীতমুখী ট্যান' চিত্র চিত্রের বাইরে আসলে (এবং খারাপভাবে কাট অফ দেখায় - প্রকাশনার মানের নয়!) এখানে চিত্র বর্ণনা লিখুন

অবশেষে, আমাকে বলা হয়েছে যে এটি আর এবং ল্যাটেক্সে স্বাভাবিক আচরণ, তাই আমি কিছুটা বিভ্রান্ত হলাম কেন অজগরটিতে এটি এত কঠিন ... কোন historicalতিহাসিক কারণ আছে? মতলব কি এই বিষয়ে সমান দরিদ্র?

আমার কাছে পেস্টবিনে এই কোডটির দীর্ঘতম সংস্করণ রয়েছে (কেবলমাত্র কিছুটা) http://pastebin.com/grVjc007


10
যতদূর এটি কেন কারণ ম্যাটপ্ল্লোলিব ইন্টারেক্টিভ প্লটের দিকে তাকাতে থাকে, যখন আর, ইত্যাদি হয় না। (এবং হ্যাঁ, মতলব এই বিশেষ ক্ষেত্রে "সমানভাবে দরিদ্র")) এটি সঠিকভাবে করার জন্য, প্রতিবার চিত্রটি পুনরায় আকার দেওয়া, জুম করা বা কিংবদন্তির অবস্থান আপডেট হওয়ার সাথে সাথে আপনাকে অক্ষগুলি পুনরায় আকার দেওয়ার বিষয়ে চিন্তা করতে হবে। (কার্যকরীভাবে, এর অর্থ প্রতিবার প্লটটি আঁকলে যাচাই করা হয় যা মন্দা বাড়ে G যা বলা হয়েছিল, tight_layout()কিংবদন্তিগুলি অ্যাকাউন্টে নেওয়ার জন্য এটি পরিবর্তন করা উচিত।
জো কিংটন

3
আমি এই প্রশ্নটি ম্যাটপ্ল্লোব ব্যবহারকারীদের মেলিং তালিকায়ও আলোচনা করছি। সুতরাং আমার কাছে সেফফিগ লাইনটি অ্যাডজাস্ট করার পরামর্শ রয়েছে: ডুমুর.সেসফিগ ('স্যাম্পলফিগুয়ার', বকবক্স_সেক্সট্রা_স্টিস্টস = (এলজিডি,), বিবক্স = 'টাইট')
জবিবিওমেড

3
আমি জানি ম্যাটপ্ল্লিটিব প্রতিটি জিনিস ব্যবহারকারীর নিয়ন্ত্রণে রয়েছে তা টাউট করতে পছন্দ করে তবে কিংবদন্তিগুলির সাথে এই পুরো জিনিসটি খুব ভাল জিনিস। আমি যদি কিংবদন্তিটি বাইরে রাখি তবে আমি অবশ্যই এটি এখনও দৃশ্যমান হোক visible এই বিশাল উদ্ধার ঝামেলা তৈরির পরিবর্তে উইন্ডোটি কেবল নিজের মাপসই করা উচিত। খুব কমপক্ষে এই অটস্কিলিং আচরণটি নিয়ন্ত্রণ করতে একটি ডিফল্ট সত্য বিকল্প থাকা উচিত। নিয়ন্ত্রণের নামে স্কেল সংখ্যাগুলি সঠিকভাবে পেতে চেষ্টা করতে এবং পুনরায় রেন্ডারগুলির একটি হাস্যকর সংখ্যার মধ্য দিয়ে যেতে ব্যবহারকারীদের বাধ্য করা বিপরীতটি সম্পাদন করে।
এলিয়ট

উত্তর:


300

দুঃখিত, ইএমএস, তবে আমি আসলে ম্যাটপ্ল্লোলিব মেলিং তালিকা থেকে আরেকটি প্রতিক্রিয়া পেয়েছি (ধন্যবাদ বেনজামিন রুটে চলে গেছে)।

আমি যে কোডটির সন্ধান করছি সেগুলি সেফফিগ কলটি এতে সামঞ্জস্য করছে:

fig.savefig('samplefigure', bbox_extra_artists=(lgd,), bbox_inches='tight')
#Note that the bbox_extra_artists must be an iterable

এটি টাইট_লেআউটকে কল করার জন্য দৃশ্যত অনুরূপ, তবে পরিবর্তে আপনি সেভফিগকে গণনায় অতিরিক্ত শিল্পীদের বিবেচনা করার অনুমতি দেন। এটি প্রকৃতপক্ষে ফিগার বাক্সটিকে পছন্দমতো আকার পরিবর্তন করেছিল।

import matplotlib.pyplot as plt
import numpy as np

plt.gcf().clear()
x = np.arange(-2*np.pi, 2*np.pi, 0.1)
fig = plt.figure(1)
ax = fig.add_subplot(111)
ax.plot(x, np.sin(x), label='Sine')
ax.plot(x, np.cos(x), label='Cosine')
ax.plot(x, np.arctan(x), label='Inverse tan')
handles, labels = ax.get_legend_handles_labels()
lgd = ax.legend(handles, labels, loc='upper center', bbox_to_anchor=(0.5,-0.1))
text = ax.text(-0.2,1.05, "Aribitrary text", transform=ax.transAxes)
ax.set_title("Trigonometry")
ax.grid('on')
fig.savefig('samplefigure', bbox_extra_artists=(lgd,text), bbox_inches='tight')

এটি উত্পাদন করে:

[সম্পাদনা] এই সমস্যার উদ্দেশ্য ছিল স্বেচ্ছাসেবক পাঠ্যের স্থূল সমন্বয়মূলক স্থাপনাগুলি সম্পূর্ণরূপে এড়ানো যেমন এই সমস্যাগুলির toতিহ্যগত সমাধান ছিল। এটি সত্ত্বেও, সম্প্রতি বেশ কয়েকটি সম্পাদনা এগুলি এগুলি দেওয়ার জন্য জোর দিয়েছিল, প্রায়শই এমন উপায়ে কোড একটি ত্রুটি বাড়ে। এগুলি কীভাবে bbox_extra_artists আলগোরিদিমের মধ্যে বিবেচনা করা হয় তা দেখানোর জন্য আমি এখন সমস্যাগুলি স্থির করেছি এবং স্বেচ্ছাচারিতা পাঠ্যকে গোছিয়েছি।



1
এটি কাজ করে পেতে পারে না :( আমি এলজিডি দিয়ে সেভফিগে পাস করি তবে এটি এখনও আকার পরিবর্তন করে না The সমস্যা হতে পারে আমি কোনও সাবপ্লট ব্যবহার করছি না
6005

8
আহ! আপনার মতো করে আমার ঠিক ববক্স_ইনস = "টাইট" ব্যবহার করা দরকার। ধন্যবাদ!
6005

7
এটি দুর্দান্ত, তবে আমি যখন চেষ্টা করি তখন আমার চিত্রটি কেটে plt.show()যায়। এর জন্য কোনও ফিক্স?
অ্যাগ্রোস্টিনো


23

যুক্ত: আমি এমন কিছু পেয়েছি যা এই মুহূর্তে কৌশলটি করা উচিত, তবে নীচের বাকী কোডগুলিও একটি বিকল্প প্রস্তাব করে।

subplots_adjust()সাবপ্লোটের নীচে উপরে সরাতে ফাংশনটি ব্যবহার করুন :

fig.subplots_adjust(bottom=0.2) # <-- Change the 0.02 to work for your plot.

তারপরে bbox_to_anchorআপনি যেখানে চান কিংবদন্তি বাক্সটি পেতে কিংবদন্তি কমান্ডের কিংবদন্তি অংশে অফসেট দিয়ে খেলুন । সেটিংস স্থাপন figsizeও ব্যবহারের কয়েকটি সমন্বয় আপনার জন্য subplots_adjust(bottom=...)একটি গুণমানের প্লট তৈরি করবে।

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

fig = plt.figure(1)

প্রতি:

fig = plt.figure(num=1, figsize=(13, 13), dpi=80, facecolor='w', edgecolor='k')

এবং পরিবর্তন

lgd = ax.legend(loc=9, bbox_to_anchor=(0.5,0))

প্রতি

lgd = ax.legend(loc=9, bbox_to_anchor=(0.5,-0.02))

এবং এটি আমার স্ক্রিনে একটি 24 ইঞ্চি সিআরটি মনিটর রয়েছে fine

এখানে figsize=(M,N)ফিগার উইন্ডোটি এম ইঞ্চি বাই এন ইঞ্চি সেট করে। এটি আপনার জন্য সঠিক না হওয়া পর্যন্ত কেবল এটির সাথে খেলুন। এটিকে আরও স্কেলযোগ্য ইমেজ ফর্ম্যাটে রূপান্তর করুন এবং প্রয়োজনে সম্পাদনা করতে জিআইএমপি ব্যবহার করুন বা viewportগ্রাফিক্স অন্তর্ভুক্ত করার সময় লটেক্স বিকল্পটি দিয়ে ক্রপ করুন ।


মনে হয় এটি বর্তমান সময়ে এটি সেরা সমাধান, যদিও এটি এখনও 'ভাল না লাগা পর্যন্ত খেলতে' প্রয়োজন যা কোনও অটোরিপোর্ট জেনারেটরের পক্ষে ভাল সমাধান নয়। আমি প্রকৃতপক্ষে এই সমাধানটি ইতিমধ্যে ব্যবহার করেছি, আসল সমস্যাটি হ'ল ম্যাটপ্ল্লিটিব অ্যাক্সেসের বাক্সের বাইরে থাকা কিংবদন্তির জন্য গতিশীল ক্ষতিপূরণ দেয় না। @ জো যেমন বলেছেন, টাইট_এলআউটকে কেবল অক্ষ, শিরোনাম এবং লেবেলের চেয়ে আরও বেশি বৈশিষ্ট্য বিবেচনা করা উচিত । আমি ম্যাটপ্লোটিলেব-তে এটি একটি বৈশিষ্ট্য অনুরোধ হিসাবে যুক্ত করতে পারি।
jbbiomed

পূর্বে কেটে যাওয়া xlabel ফিট করার জন্য আমার জন্য যথেষ্ট বড় ছবি পাওয়ার জন্যও কাজ করে
ফ্রেডরিক নর্ড

1
এখানে matplotlib.org থেকে উদাহরণ কোড সহ ডকুমেন্টেশন রয়েছে
Yojimbo

14

এখানে অন্য একটি খুব ম্যানুয়াল সমাধান। আপনি অক্ষের আকার নির্ধারণ করতে পারেন এবং প্যাডিংগুলি সেই অনুযায়ী বিবেচনা করা হয় (কিংবদন্তি এবং টিকমার্ক সহ)। আশা করি এটি কারও কাজে আসবে।

উদাহরণ (অক্ষের আকার একই!):

এখানে চিত্র বর্ণনা লিখুন

কোড:

#==================================================
# Plot table

colmap = [(0,0,1) #blue
         ,(1,0,0) #red
         ,(0,1,0) #green
         ,(1,1,0) #yellow
         ,(1,0,1) #magenta
         ,(1,0.5,0.5) #pink
         ,(0.5,0.5,0.5) #gray
         ,(0.5,0,0) #brown
         ,(1,0.5,0) #orange
         ]


import matplotlib.pyplot as plt
import numpy as np

import collections
df = collections.OrderedDict()
df['labels']        = ['GWP100a\n[kgCO2eq]\n\nasedf\nasdf\nadfs','human\n[pts]','ressource\n[pts]'] 
df['all-petroleum long name'] = [3,5,2]
df['all-electric']  = [5.5, 1, 3]
df['HEV']           = [3.5, 2, 1]
df['PHEV']          = [3.5, 2, 1]

numLabels = len(df.values()[0])
numItems = len(df)-1
posX = np.arange(numLabels)+1
width = 1.0/(numItems+1)

fig = plt.figure(figsize=(2,2))
ax = fig.add_subplot(111)
for iiItem in range(1,numItems+1):
  ax.bar(posX+(iiItem-1)*width, df.values()[iiItem], width, color=colmap[iiItem-1], label=df.keys()[iiItem])
ax.set(xticks=posX+width*(0.5*numItems), xticklabels=df['labels'])

#--------------------------------------------------
# Change padding and margins, insert legend

fig.tight_layout() #tight margins
leg = ax.legend(loc='upper left', bbox_to_anchor=(1.02, 1), borderaxespad=0)
plt.draw() #to know size of legend

padLeft   = ax.get_position().x0 * fig.get_size_inches()[0]
padBottom = ax.get_position().y0 * fig.get_size_inches()[1]
padTop    = ( 1 - ax.get_position().y0 - ax.get_position().height ) * fig.get_size_inches()[1]
padRight  = ( 1 - ax.get_position().x0 - ax.get_position().width ) * fig.get_size_inches()[0]
dpi       = fig.get_dpi()
padLegend = ax.get_legend().get_frame().get_width() / dpi 

widthAx = 3 #inches
heightAx = 3 #inches
widthTot = widthAx+padLeft+padRight+padLegend
heightTot = heightAx+padTop+padBottom

# resize ipython window (optional)
posScreenX = 1366/2-10 #pixel
posScreenY = 0 #pixel
canvasPadding = 6 #pixel
canvasBottom = 40 #pixel
ipythonWindowSize = '{0}x{1}+{2}+{3}'.format(int(round(widthTot*dpi))+2*canvasPadding
                                            ,int(round(heightTot*dpi))+2*canvasPadding+canvasBottom
                                            ,posScreenX,posScreenY)
fig.canvas._tkcanvas.master.geometry(ipythonWindowSize) 
plt.draw() #to resize ipython window. Has to be done BEFORE figure resizing!

# set figure size and ax position
fig.set_size_inches(widthTot,heightTot)
ax.set_position([padLeft/widthTot, padBottom/heightTot, widthAx/widthTot, heightAx/heightTot])
plt.draw()
plt.show()
#--------------------------------------------------
#==================================================

এই পর্যন্ত আমি প্রথম পরিবর্তিত আমাকে জন্য কাজ না করে plt.draw()করতে ax.figure.canvas.draw()। আমি নিশ্চিত না কেন তবে এই পরিবর্তনের আগে কিংবদন্তির আকার আপডেট হচ্ছে না।
ws_e_c421

আপনি যদি এটি কোনও জিইউআই উইন্ডোতে ব্যবহার করার চেষ্টা করছেন তবে আপনাকে এতে পরিবর্তন fig.set_size_inches(widthTot,heightTot)করা দরকার fig.set_size_inches(widthTot,heightTot, forward=True)
ws_e_c421
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.