ম্যাটপ্ল্লোব প্লটগুলি: অক্ষ, কিংবদন্তি এবং সাদা স্থানগুলি সরিয়ে ফেলা হচ্ছে


285

আমি পাইথন এবং ম্যাটপ্ল্লোলিবের কাছে নতুন, আমি কুড়াল, লেবেল, শিরোনাম বা ম্যাটপ্ল্লোব দ্বারা সাধারণত স্বয়ংক্রিয়ভাবে যুক্ত কিছু ব্যবহার না করে কোনও চিত্রের জন্য রঙিন্যাপ প্রয়োগ করতে এবং ফলস্বরূপ চিত্রটি লিখতে চাই। আমি যা করেছি তা এখানে:

def make_image(inputname,outputname):
    data = mpimg.imread(inputname)[:,:,0]
    fig = plt.imshow(data)
    fig.set_cmap('hot')
    fig.axes.get_xaxis().set_visible(False)
    fig.axes.get_yaxis().set_visible(False)
    plt.savefig(outputname)

এটি সাফল্যের সাথে চিত্রটির অক্ষটি সরিয়ে দেয়, তবে সংরক্ষিত চিত্রটি একটি সত্যিকারের চিত্রের চারপাশে একটি সাদা প্যাডিং এবং একটি ফ্রেম উপস্থাপন করে। আমি কীভাবে এগুলি সরিয়ে ফেলব (কমপক্ষে সাদা প্যাডিং)? ধন্যবাদ


2
এই প্রশ্নের সমস্ত সমাধান ফোকাস করা হয় imshow। পরিবর্তে যদি আপনার কাছে স্ক্যাটারপ্লট থাকে তবে নীচের উত্তরগুলি আপনাকে সহায়তা করতে পারে: stackoverflow.com/a/40727744/4124317
ImportanceOfBeingEnnest

উত্তর:


373

আমি মনে করি যে কমান্ডটি axis('off')প্রতিটি অক্ষ এবং সীমানাকে পৃথকভাবে পরিবর্তনের চেয়ে আরও সংক্ষেপে সমস্যার সমাধান করে of এটি এখনও সীমান্তের চারপাশে সাদা স্থান ছেড়ে দেয়। কমান্ডে যোগ bbox_inches='tight'করা savefigপ্রায় আপনাকে সেখানে পৌঁছে দেয় , আপনি নীচের উদাহরণে দেখতে পাচ্ছেন যে সাদা স্থানটি বাকী অনেক কম, তবে এখনও উপস্থিত রয়েছে।

নোট করুন ম্যাটপ্লটলিবের নতুন সংস্করণগুলির bbox_inches=0স্ট্রিংয়ের পরিবর্তে 'tight'(@ অ্যাপসিডিয়াং এবং @ ক্যাট্রাচের মাধ্যমে) প্রয়োজন হতে পারে

from numpy import random
import matplotlib.pyplot as plt

data = random.random((5,5))
img = plt.imshow(data, interpolation='nearest')
img.set_cmap('hot')
plt.axis('off')
plt.savefig("test.png", bbox_inches='tight')

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


4
Unutbu এর পরামর্শ অনুসরণ করে আপনি ব্যবহার করতে পারে fig = plt.figure(), ax = plt.axes([0,0,1,1])তারপর, plt.imshow(data,interpolation="nearest"। এর সাথে সম্মিলিতভাবে plt.axis("off")এটি ইমেজের পাশে থাকা সমস্ত কিছু থেকে মুক্তি পাওয়া উচিত, আশা করি!
ফিলম্যাককে

5
প্রশ্ন থেকে পদ্ধতিগুলির সংমিশ্রণ ({fig.axes.get_xaxis ()। সেট_ভিজিবল (মিথ্যা) এবং চিত্র.অ্যাক্সেস। আমাকে. (আর কোনও শ্বেতস্থান নেই)। আর আত 0. আপনার savefig মধ্যে {pad_inches} সেট করতে ভুলবেন
Domagoj

3
আমি কেবল এই ইস্যুটি জুড়ে দৌড়েছি, এই থ্রেডের কোনও সমাধান, এবং যুক্ত লিঙ্কগুলি, কাজ করে না। তবে স্পষ্টভাবে নির্দিষ্ট bbox_inches=0করে কৌশলটি করেছে।
কাদরাচ

1
মনে রাখবেন যে আপনি plt.imshow- এর উপর স্টাটগুলি 'প্লট' করছেন, যেমন plt.plot (x, y) এর মতো, আপনি ম্যাট্রিক্সের আকারে xlim এবং ylim সেট করেছেন তা নিশ্চিত করতে হবে।
Mathusalem

1
এটি আর কাজ করে না। এটি বের করার জন্য আমাকে এক ঘন্টা সময় নিয়েছে। নীচে উত্তর দেখুন।
এপিডিয়াং

107

আমি এই কৌশলটি এখানে মতেহাট থেকে শিখেছি :

import matplotlib.pyplot as plt
import numpy as np

def make_image(data, outputname, size=(1, 1), dpi=80):
    fig = plt.figure()
    fig.set_size_inches(size)
    ax = plt.Axes(fig, [0., 0., 1., 1.])
    ax.set_axis_off()
    fig.add_axes(ax)
    plt.set_cmap('hot')
    ax.imshow(data, aspect='equal')
    plt.savefig(outputname, dpi=dpi)

# data = mpimg.imread(inputname)[:,:,0]
data = np.arange(1,10).reshape((3, 3))

make_image(data, '/tmp/out.png')

উৎপাদনের

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


3
আমি নিশ্চিত যে আপনার সঠিক উত্তর রয়েছে (যদিও এটি করার একাধিক উপায় রয়েছে) তবে আমি ভাবছি আপনি কেন এটি সঠিক উত্তরটি ব্যাখ্যা করতে পারেন কিনা ? আপনার কোড সম্পর্কে কী সাদা স্থান সরিয়ে দেয়?
ইয়ান

4
@ ইয়ান, ডকুমেন্টেশন ছাড়াও, প্রতিটি কমান্ডের কী প্রভাব আছে তা দেখার জন্য আমি একবারে একটি লাইন মন্তব্য করা খুব সহায়ক বলে মনে করি। এটা অভিজ্ঞতা অভিজ্ঞতা!
unutbu

4
সাদা সীমানা সরিয়ে রেখাটি হ'ল plt.Axes(fig, [0,0,1,1])। এটি ম্যাটপ্ল্লোলিবকে নীচে বাম কোণে (0%, 0%) অবস্থিত এবং প্রস্থ এবং উচ্চতা (100%, 100%) সহ একটি অক্ষের একটি সেট তৈরি করতে বলে।
ফিলম্যাকেকে

এটি আরও সঠিক উত্তর, কারণ এটি কেবল সংরক্ষিত চিত্রের জন্য নয় অনস্ক্রিন প্লটের জন্যও সাদা স্থান সরিয়ে দেয়।
ম্যাক্সনয়ে

ধন্যবাদ, এটি কেবলমাত্র আমার উবুন্টুতে সমাধানটি সমাধান করে :)
AlphaGoMK

56

সম্ভাব্য সহজ সমাধান:

আমি কেবল প্রশ্নে বর্ণিত পদ্ধতি এবং হুকডের উত্তর থেকে পদ্ধতিটি একত্রিত করেছি।

fig = plt.imshow(my_data)
plt.axis('off')
fig.axes.get_xaxis().set_visible(False)
fig.axes.get_yaxis().set_visible(False)
plt.savefig('pict.png', bbox_inches='tight', pad_inches = 0)

এই কোডের পরে কোনও সাদা স্থান এবং কোনও ফ্রেম নেই।

কোনও সাদা জায়গা, অক্ষ বা ফ্রেম নেই


3
আপনার পদ্ধতিটি এই চিত্রটির চারপাশের সমস্ত সাদা স্পেস সরিয়ে ফেলেছে, ভাল কাজ, তবে এখনও কেন জানি না কেন কমান্ড যুক্ত fig.axes.get_xaxis().set_visible(False)করে সমস্যার সমাধান করে। ধন্যবাদ
ollydbg23

5
হ্যাঁ আপনি যদি এই আদেশগুলি না কল করেন তবে বেশিরভাগ সাদা স্পেস সরিয়ে দেওয়া হবে। তবে আমার ক্ষেত্রে আমার প্লট এবং .png চিত্রের প্রান্তের মধ্যে এখনও কিছু জায়গা রয়েছে (সম্ভবত 2px প্রশস্ত)। নিম্নলিখিত কমান্ডগুলিতে ফোন করে আমি এই জেদী জায়গা থেকে মুক্তি পেয়েছি।
দোমগোজ

3
দ্রষ্টব্য, যদিও, একই চিত্রটিতে একাধিক অক্ষের উপস্থিতিতে উপরেরগুলি ব্যর্থ হবে (আমার ক্ষেত্রে প্লটে একটি এমবেডেড চিত্র)। সমাধান: fig.axes[0]এবং সাধারণভাবে সমস্ত বা নির্বাচিত অক্ষ।
অয়নিস ফিলিপিসিস

29

imsaveএখনও কেউ উল্লেখ করেনি, যা এটি ওয়ান লাইনার করে তোলে:

import matplotlib.pyplot as plt
import numpy as np

data = np.arange(10000).reshape((100, 100))
plt.imsave("/tmp/foo.png", data, format="png", cmap="hot")

এটি চিত্রটি যেমন আছে তেমন সরাসরি সঞ্চয় করে, অর্থাৎ কোনও অক্ষ বা সীমানা / প্যাডিং যুক্ত করে না।

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


আমি বেশিরভাগ সময় এটিই করি, তবে রঙিনবারের প্রয়োজন হলে এমন উদাহরণ রয়েছে এবং এই ক্ষেত্রে ইমস্যাভ আমাকে বাঁচাতে পারে না।
ইলিয়াস

9

আপনি bbox_inchesআর্গুমেন্টের ব্যাপ্তিটিও নির্দিষ্ট করতে পারেন । এটি চিত্রের চারপাশে সাদা প্যাডিং থেকে মুক্তি পাবে।

def make_image(inputname,outputname):
    data = mpimg.imread(inputname)[:,:,0]
    fig = plt.imshow(data)
    fig.set_cmap('hot')
    ax = fig.gca()
    ax.set_axis_off()
    ax.autoscale(False)
    extent = ax.get_window_extent().transformed(plt.gcf().dpi_scale_trans.inverted())
    plt.savefig(outputname, bbox_inches=extent)

8

এর ফলে সমস্ত প্যাডিং এবং সীমানা মুছে ফেলা উচিত:

from matplotlib import pyplot as plt

fig = plt.figure()
fig.patch.set_visible(False)

ax = fig.add_subplot(111)

plt.axis('off')
plt.imshow(data)

extent = ax.get_window_extent().transformed(fig.dpi_scale_trans.inverted())
plt.savefig("../images/test.png", bbox_inches=extent)

আন্ডাররেটেড উত্তর! এটি আমাকে সেখানে 99% পথের মতো পেয়েছে। এটি আরও আপগ্রেটেড হওয়া উচিত কারণ এটি সর্বাধিক আপ টু ডেট
নাথান

আপনার অ্যাক্সেস অবজেক্ট ( ax) না থাকলে এটিও কাজ করে extent = plt.gca().get_window_extent().transformed(fig.dpi_scale_trans.inverted())
টোস্ট

4

আমি দেখতে পেয়েছি যে এটি সমস্ত নথিভুক্ত ...

https://matplotlib.org/3.1.1/api/_as_gen/matplotlib.axes.Axes.axis.html#matplotlib.axes.Axes.axis

আমার কোড…। "বিসিকে" একটি 512x512 চিত্র

plt.figure()
plt.imshow(bck)
plt.axis("off")   # turns off axes
plt.axis("tight")  # gets rid of white border
plt.axis("image")  # square up the image instead of filling the "figure" space
plt.show()

3

Upvated উত্তর আর কাজ করে না। এটি কাজ করতে আপনাকে ম্যানুয়ালি একটি অক্ষ সেট [0, 0, 1, 1] এ যুক্ত করতে হবে বা চিত্রের অধীনে প্যাচটি সরিয়ে ফেলতে হবে।

import matplotlib.pyplot as plt

fig = plt.figure(figsize=(5, 5), dpi=20)
ax = plt.Axes(fig, [0., 0., 1., 1.])
fig.add_axes(ax)
plt.imshow([[0, 1], [0.5, 0]], interpolation="nearest")
plt.axis('off')                                # same as: ax.set_axis_off()

plt.savefig("test.png")

বিকল্পভাবে, আপনি কেবল প্যাচটি সরাতে পারেন। প্যাডিংগুলি সরানোর জন্য আপনাকে একটি সাবপ্লট যোগ করার দরকার নেই। নীচে ভ্ল্যাডি এর উত্তর থেকে এটি সরল করা হয়েছে

fig = plt.figure(figsize=(5, 5))
fig.patch.set_visible(False)                   # turn off the patch

plt.imshow([[0, 1], [0.5, 0]], interpolation="nearest")
plt.axis('off')

plt.savefig("test.png", cmap='hot')

এটি 3.0.32019/06/19 সংস্করণ দিয়ে পরীক্ষা করা হয় । চিত্র দেখুন নিচু:

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

খুব সহজ কাজটি হ'ল ব্যবহার করা pyplot.imsave। বিশদগুলির জন্য, লুয়েটারের উত্তরটি নীচে দেখুন


আমার জন্য কেবল অ্যাক্সেস সংস্করণ কাজ করে। আমি প্যাচ বন্ধ সংস্করণ দিয়ে প্যাডিং পেতে। যাইহোক!
সেভ_জেফ

2

আমি উবুন্টুর উত্তর পছন্দ করেছি , তবে এটি বাক্সের বাইরে-বর্গক্ষেত্রের চিত্রগুলির জন্য কীভাবে আকার নির্ধারণ করতে হবে তা স্পষ্টভাবে দেখাচ্ছে না, তাই আমি অনুলিপি-অনুলিপি সহজে কপি-পেস্টের জন্য এটি সংশোধন করেছি:

import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import numpy as np

def save_image_fix_dpi(data, dpi=100):
    shape=np.shape(data)[0:2][::-1]
    size = [float(i)/dpi for i in shape]

    fig = plt.figure()
    fig.set_size_inches(size)
    ax = plt.Axes(fig,[0,0,1,1])
    ax.set_axis_off()
    fig.add_axes(ax)
    ax.imshow(data)
    fig.savefig('out.png', dpi=dpi)
    plt.show()

পিক্সেল_সাইজ / ডিপিআই = আকার রাখে তবে বর্ডার ছাড়াই চিত্রগুলি সংরক্ষণ করা সহজ আপনি ডিপিআই চয়ন করুন।

data = mpimg.imread('test.png')
save_image_fix_dpi(data, dpi=100)

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

তবে প্রদর্শিত হয় বিদ্বেষপূর্ণ। আপনি যদি ছোট ডিপিআই চয়ন করেন তবে আপনার চিত্রের আকারটি আপনার স্ক্রিনের চেয়ে বড় হতে পারে এবং আপনি প্রদর্শনের সময় সীমানা পান। তবুও, এটি সংরক্ষণকে প্রভাবিত করে না।

অনেক দূরে

save_image_fix_dpi(data, dpi=20)

প্রদর্শনটি সীমান্তে পরিণত হয় (তবে সংরক্ষণের কাজগুলি): এখানে চিত্র বর্ণনা লিখুন


1

প্রথমত, নির্দিষ্ট চিত্রের ফর্ম্যাটগুলির জন্য (অর্থাত্ টিআইএফএফ ) আপনি আসলে শিরোনামে রঙিন মানচিত্র সংরক্ষণ করতে পারেন এবং বেশিরভাগ দর্শক রঙিনম্যাপের সাহায্যে আপনার ডেটা প্রদর্শন করবেন।

একটি প্রকৃত matplotlibচিত্র সংরক্ষণের জন্য , যা চিত্রগুলিতে টীকাগুলি বা অন্যান্য ডেটা যুক্ত করতে কার্যকর হতে পারে, আমি নিম্নলিখিত সমাধানটি ব্যবহার করেছি:

fig, ax = plt.subplots(figsize=inches)
ax.matshow(data)  # or you can use also imshow
# add annotations or anything else
# The code below essentially moves your plot so that the upper
# left hand corner coincides with the upper left hand corner
# of the artist
fig.subplots_adjust(left=0, right=1, top=1, bottom=0, wspace=0, hspace=0)
# now generate a Bbox instance that is the same size as your
# single axis size (this bbox will only encompass your figure)
bbox = matplotlib.transforms.Bbox(((0, 0), inches))
# now you can save only the part of the figure with data
fig.savefig(savename, bbox_inches=bbox, **kwargs)

0

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

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

সুতরাং আমি যা করে শেষ করেছি তা হ'ল ডেভিডের উত্তরটি স্নিমেসের সাথে সংযুক্ত করে চিত্রটি তৈরির সময় একটি সাধারণ মোড়ক তৈরি করতে। আপনি যখন এটি ব্যবহার করেন, আপনার পরে ইমস্যাভ () বা অন্য কোনও কিছু দিয়ে কোনও পরিবর্তন প্রয়োজন হবে না:

def get_img_figure(image, dpi):
    """
    Create a matplotlib (figure,axes) for an image (numpy array) setup so that
        a) axes will span the entire figure (when saved no whitespace)
        b) when saved the figure will have the same x/y resolution as the array, 
           with the dpi value you pass in.

    Arguments:
        image -- numpy 2d array
        dpi -- dpi value that the figure should use

    Returns: (figure, ax) tuple from plt.subplots
    """

    # get required figure size in inches (reversed row/column order)
    inches = image.shape[1]/dpi, image.shape[0]/dpi

    # make figure with that size and a single axes
    fig, ax = plt.subplots(figsize=inches, dpi=dpi)

    # move axes to span entire figure area
    fig.subplots_adjust(left=0, right=1, top=1, bottom=0, wspace=0, hspace=0)

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