আমি কীভাবে ম্যাটপ্লোটিলেবতে অনুপাত নির্ধারণ করতে পারি?


108

আমি একটি বর্গাকার প্লট (ইমশো ব্যবহার করে) তৈরি করার চেষ্টা করছি, অর্থাত: 1: 1 এর অনুপাত, কিন্তু আমি করতে পারি না। এই কাজের কোনওটিই নয়:

import matplotlib.pyplot as plt

ax = fig.add_subplot(111,aspect='equal')
ax = fig.add_subplot(111,aspect=1.0)
ax.set_aspect('equal')
plt.axes().set_aspect('equal')

দেখে মনে হচ্ছে কলগুলি কেবল উপেক্ষা করা হচ্ছে (এমন একটি সমস্যা যা আমি প্রায়শই ম্যাটপ্ল্লিটিবের সাথে মনে করি)।


6
আপনি কি ax.axis('equal')সুযোগ পেয়ে চেষ্টা করেছেন? যেমনটি সবাই বলেছে, আপনার যা করা উচিত তা কাজ করা উচিত তবে কাজের ax.axisপথের চেষ্টা করার জন্য এটি অন্য কোনও পথ হতে পারে।
জো কিংটন

উত্তর:


77

তৃতীয় বার কবজ। আমার অনুমান যে এটি একটি বাগ এবং ঝেনিয়ার উত্তর থেকে জানা যায় যে এটি সর্বশেষতম সংস্করণে স্থির হয়েছে। আমার কাছে 0.99.1.1 সংস্করণ রয়েছে এবং আমি নিম্নলিখিত সমাধানটি তৈরি করেছি:

import matplotlib.pyplot as plt
import numpy as np

def forceAspect(ax,aspect=1):
    im = ax.get_images()
    extent =  im[0].get_extent()
    ax.set_aspect(abs((extent[1]-extent[0])/(extent[3]-extent[2]))/aspect)

data = np.random.rand(10,20)

fig = plt.figure()
ax = fig.add_subplot(111)
ax.imshow(data)
ax.set_xlabel('xlabel')
ax.set_aspect(2)
fig.savefig('equal.png')
ax.set_aspect('auto')
fig.savefig('auto.png')
forceAspect(ax,aspect=1)
fig.savefig('force.png')

এটি 'ফোর্স.পিএনজি': এখানে চিত্র বর্ণনা লিখুন

নীচে আমার ব্যর্থ, তবুও আশাবাদী তথ্যমূলক প্রচেষ্টা রয়েছে।

দ্বিতীয় উত্তর:

নীচে আমার 'আসল উত্তর' ওভারকিল, যেমন এটির মতো কিছু করে axes.set_aspect()। আমি মনে করি আপনি ব্যবহার করতে চান axes.set_aspect('auto')। আমি কেন বুঝতে পারছি না এটি কেন, তবে এটি আমার জন্য বর্গাকার চিত্রের প্লট তৈরি করে, উদাহরণস্বরূপ এই স্ক্রিপ্ট:

import matplotlib.pyplot as plt
import numpy as np

data = np.random.rand(10,20)

fig = plt.figure()
ax = fig.add_subplot(111)
ax.imshow(data)
ax.set_aspect('equal')
fig.savefig('equal.png')
ax.set_aspect('auto')
fig.savefig('auto.png')

'সমান' দিক অনুপাত সহ একটি চিত্র প্লট তৈরি করে: এখানে চিত্র বর্ণনা লিখুন এবং 'অটো' দিক অনুপাত সহ একটি: এখানে চিত্র বর্ণনা লিখুন

'মূল উত্তর' এর নীচে প্রদত্ত কোডটি একটি সুস্পষ্টভাবে নিয়ন্ত্রিত দিক অনুপাতের জন্য একটি প্রারম্ভিক বিন্দু সরবরাহ করে, তবে মনে হয় এটি একবার প্রদর্শিত হবে।

আসল উত্তর:

এখানে একটি রুটিনের উদাহরণ যা সাবপ্লট প্যারামিটারগুলিকে সামঞ্জস্য করবে যাতে আপনি পছন্দসই দিক অনুপাত পাবেন:

import matplotlib.pyplot as plt

def adjustFigAspect(fig,aspect=1):
    '''
    Adjust the subplot parameters so that the figure has the correct
    aspect ratio.
    '''
    xsize,ysize = fig.get_size_inches()
    minsize = min(xsize,ysize)
    xlim = .4*minsize/xsize
    ylim = .4*minsize/ysize
    if aspect < 1:
        xlim *= aspect
    else:
        ylim /= aspect
    fig.subplots_adjust(left=.5-xlim,
                        right=.5+xlim,
                        bottom=.5-ylim,
                        top=.5+ylim)

fig = plt.figure()
adjustFigAspect(fig,aspect=.5)
ax = fig.add_subplot(111)
ax.plot(range(10),range(10))

fig.savefig('axAspect.png')

এটি এর মতো একটি চিত্র তৈরি করে: এখানে চিত্র বর্ণনা লিখুন

আমি ভাবতে পারি যদি চিত্রের মধ্যে আপনার একাধিক সাবপ্লট থাকে, আপনি সরবরাহিত রুটিনে কী এবং প্যারামিটারগুলি (প্রতিটি 1 এর ডিফল্ট) হিসাবে y এবং x সাবপ্লটগুলির সংখ্যা অন্তর্ভুক্ত করতে চান। 'সেই সংখ্যা এবং ব্যবহার hspaceএবং wspaceকীওয়ার্ড, আপনি সব subplots সঠিক অনুপাত আছে করতে পারেন।


1
যেসব ক্ষেত্রে get_imagesখালি তালিকা রয়েছে (যেমনটি ঘটতে পারে ax.plot([0,1],[0,2]), আপনি ব্যবহার করতে পারেন get_xlimএবংget_ylim
জোয়েল

আমার কাছে দেখে মনে হচ্ছে লগস্কেল দিয়ে কাজ করলে এটি কাজ করবে না। আমি একটি উত্তর যুক্ত করেছি যা এটির জন্য পরীক্ষা করে এবং পরিচালনা করে। আপনার উত্তরের সাথে নিখরচায় এটিকে সংযোজন করুন এবং তারপরে আমি আমার সরিয়ে ফেলব।
জোয়েল

1
দিকটি অসম দেখায় এমন কারণ হ'ল সমান দিকের অর্থ x এর চাক্ষুষ দূরত্বটি y এর সমান হবে। যদি চিত্রটি বর্গক্ষেত্র হয় তবে প্লট ডিএক্স এবং ডাই আলাদা হয়, তবে এটি 1: 1 আকৃতির অনুপাত নয়। ক্ষেত্রে অনুপাতটি dy / dx হবে।
বার্ট কিউরিচ

22

আপনি যে matplotlibসংস্করণটি চালাচ্ছেন তা কী? আমাকে সম্প্রতি আপগ্রেড করতে হয়েছিল 1.1.0এবং এটি দিয়ে add_subplot(111,aspect='equal')আমার জন্য কাজ করে।


1
matplotlibসংস্করণে আমার জন্য ভাল কাজ করে 2.0.2jupyter notebookসংস্করণ 5.0.0। ধন্যবাদ।
সতীশ

5

উপরের উত্তরগুলি সহ বহুবছর সাফল্যের পরেও আমি এটি আবার কাজ না করার জন্য পেয়েছি - তবে আমি সাবপ্লটগুলির জন্য একটি কার্যকর সমাধান খুঁজে পেয়েছি

https://jdhao.github.io/2017/06/03/change-aspect-ratio-in-mpl

উপরের লেখকের কাছে অবশ্যই সম্পূর্ণ কৃতিত্বের সাথে (যিনি সম্ভবত এখানে পোস্ট করতে পারেন), সম্পর্কিত লাইনগুলি হ'ল:

ratio = 1.0
xleft, xright = ax.get_xlim()
ybottom, ytop = ax.get_ylim()
ax.set_aspect(abs((xright-xleft)/(ybottom-ytop))*ratio)

লিঙ্কটিতে ম্যাটপ্ল্লোব দ্বারা ব্যবহৃত বিভিন্ন স্থানাঙ্ক সিস্টেমগুলির একটি স্ফটিক স্পষ্ট ব্যাখ্যা রয়েছে।

সমস্ত দুর্দান্ত উত্তরের জন্য ধন্যবাদ - বিশেষত @ ইয়ান এর যা বিজয়ী থাকবে।


3

আপনার ফিগার দিয়ে চেষ্টা করা উচিত। এটা আমার জন্য কাজ করে. ডক্স থেকে:

নির্দিষ্ট দিক অনুপাত সহ একটি চিত্র তৈরি করুন। তাহলে ARG একটি নম্বর ব্যবহার এই অনুপাত হয়। > যদি ARG একটি অ্যারের, figaspect প্রস্থ এবং একটি চিত্র যে মাপসই করা হবে অ্যারের অনুপাত সংরক্ষণের জন্য উচ্চতা নির্ধারণ করা হবে। চিত্রের প্রস্থ, উচ্চতা ইঞ্চি ফিরে আসবে। সমান এবং উচ্চতা সহ একটি অক্ষ তৈরি করতে ভুলবেন না, যেমন

ব্যবহারের উদাহরণ:

  # make a figure twice as tall as it is wide
  w, h = figaspect(2.)
  fig = Figure(figsize=(w,h))
  ax = fig.add_axes([0.1, 0.1, 0.8, 0.8])
  ax.imshow(A, **kwargs)

  # make a figure with the proper aspect for an array
  A = rand(5,3)
  w, h = figaspect(A)
  fig = Figure(figsize=(w,h))
  ax = fig.add_axes([0.1, 0.1, 0.8, 0.8])
  ax.imshow(A, **kwargs)

সম্পাদনা: আপনি কী সন্ধান করছেন তা সম্পর্কে আমি নিশ্চিত নই। উপরের কোডটি ক্যানভাস (প্লটের আকার) পরিবর্তন করে। আপনি যদি চিত্রটির ম্যাটপ্ল্লোটিব উইন্ডোর আকার পরিবর্তন করতে চান তবে ব্যবহার করুন:

In [68]: f = figure(figsize=(5,1))

এটি 5x1 (ডাব্লুএক্সএইচ) এর একটি উইন্ডো তৈরি করে।


এর জন্য ধন্যবাদ - এটি ক্যানভাসের দিক অনুপাত পরিবর্তনের ক্ষেত্রে কিছুটা প্রভাব ফেলেছে: আরও নির্দিষ্ট করে বলার জন্য, আমাকে নিজেই চিত্রটির দিকের অনুপাতটি পরিবর্তন করতে হবে, যা নিম্নলিখিতগুলি করে না (অ্যাপল ফর্ম্যাটিং ..): ডুমুর = plt.figure (figsize = (plt.figaspect (2.0)))
jtlz2

3

এই উত্তর ইয়ানের উত্তরের উপর ভিত্তি করে তৈরি। এটি লিনিয়ার বা লগ-লগ প্লটের জন্য দিক অনুপাত সেট করবে। অক্ষগুলি লগ-স্কেল কিনা তা পরীক্ষা করতে আমি https://stackoverflow.com/a/16290035/2966723 থেকে অতিরিক্ত তথ্য ব্যবহার করেছি ।

def forceAspect(ax,aspect=1):
    #aspect is width/height
    scale_str = ax.get_yaxis().get_scale()
    xmin,xmax = ax.get_xlim()
    ymin,ymax = ax.get_ylim()
    if scale_str=='linear':
        asp = abs((xmax-xmin)/(ymax-ymin))/aspect
    elif scale_str=='log':
        asp = abs((scipy.log(xmax)-scipy.log(xmin))/(scipy.log(ymax)-scipy.log(ymin)))/aspect
    ax.set_aspect(asp)

স্পষ্টতই আপনি যে কোনও সংস্করণ ব্যবহার logকরতে পারেন, আমি ব্যবহার করেছি scipy, তবে numpyবা ঠিক mathথাকতে হবে।

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