scipy:フレーム、軸なし、コンテンツのみのsavefig


92

numpy / scipyには、画像が配列に格納されています。表示できます。境界線、軸、ラベル、タイトルなどを使用savefig せずに保存したいと思います。純粋な画像だけで、他には何もありません。

PyPNGまたはのようなパッケージは避けたいのですがscipy.misc.imsave、問題が発生することがあります(常にうまくインストールされるとは限らずsavefig()、私にとっては基本的なものにすぎません)

回答:


118

編集

変更aspect='normalaspect='auto'matplotlibのより新しいバージョン(@ Luke19のおかげで)に変更しているからです。


仮定:

import matplotlib.pyplot as plt

フレームなしでフィギュアを作るには:

fig = plt.figure(frameon=False)
fig.set_size_inches(w,h)

コンテンツを図全体に表示するには

ax = plt.Axes(fig, [0., 0., 1., 1.])
ax.set_axis_off()
fig.add_axes(ax)

次に、その上に画像を描きます。

ax.imshow(your_image, aspect='auto')
fig.savefig(fname, dpi)

このaspectパラメーターは、ピクセルサイズを変更して、で指定された図のサイズを確実に満たすようにしfig.set_size_inches(…)ます。この種のもので遊ぶ方法の感触をつかむために、特にAxes、Axis、Artistの主題に関するmatplotlibのドキュメントを読んでください。


4
いいえ、まだ小さな透明な境界線があります。必要なのは境界線まったくない、純粋な画像
Jakub M.

5
手動で設定する場合whでパラメータfig.set_size_inches(w,h)dpiのパラメータをfig.savefig(fname, dpi)ので、それが24ピクセルでは24pxになること、それがうまく動作するはずです。たとえば、w = h = 1およびdpi = 24
matehat 2011年

5
私はこの答えとMostafaPakparvarによる以下の答えの両方を組み合わせる必要がありました。軸をオフにする必要があるだけでなく、空白が確実に消えるようにset_visibleをfalseに設定する必要があります。(wtf?)
ブライスギンタ2016年

6
matplotlib v2.2.2を使用してこれを試したところ、完全に機能しました(ただし、imshowの構文がではaspect='auto'なくに変更されました'normal')。
Luke 1918

2
これは正しいアプローチです。ax = plt.Axes(fig, [0., 0., 1., 1.])それを機能させるものです。
greatvovan

73

より簡単な解決策は次のようです:

fig.savefig('out.png', bbox_inches='tight', pad_inches=0)

2
これは私にとって素晴らしいことでした。また、pad_inchesは簡単に希望のサイズに変更できます。ありがとう!
Curious2learn 2012

27
私はまだこれで白いマージンを得ました。
ファビアンペレス

5
透明= Trueを追加するだけで、新しいバージョン/残りのマージンの問題についてこれを更新できました fig.savefig('out.png', bbox_inches='tight',transparent=True, pad_inches=0)
mdoc-2011

2
まだ軸と
目盛り

3
これは何もしません。それはあなたにすべての軸とラベルであなたに図を与えるでしょう。
1313E

27

(を使用してget_window_extent)軸内の画像のbboxを見つけ、bbox_inchesパラメータを使用して画像のその部分のみを保存できます。

import numpy as np
import matplotlib.pyplot as plt

data=np.arange(9).reshape((3,3))
fig=plt.figure()
ax=fig.add_subplot(1,1,1)
plt.axis('off')
plt.imshow(data)

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

私はここでジョーキントンからこのトリックを学びました


6
plt.axis('off')助けただけです。他の答えはあまり役に立ちません。
imsrgadich 2018年

3
これはかなりうまくいきました。しかし私の場合、まだ小さな白い境界線があります。この境界線を削除する方法のアイデアはありますか?
user3731622 2018年

user3731622 @、試してみてくださいplt.savefig('/temp/test.png', bbox_inches='tight', transparent=True, pad_inches=0)代わりにplt.savefig('/tmp/test.png', bbox_inches=extent)
クラウドチョー

17

私の場合、いくつかのオプションを試しましたが、最善の解決策は次のとおりです。

fig.subplots_adjust(bottom = 0)
fig.subplots_adjust(top = 1)
fig.subplots_adjust(right = 1)
fig.subplots_adjust(left = 0)

次に、でフィギュアを保存します savefig


1
このすべてのソリューションの中で、これが私のために働いた唯一のソリューションです。
パフ

8

したがって、bboxをタイトモードに設定した後に残ったパディングを削除するために、ここから少し追加してheron13の回答を提案します。

axes = fig.axes()
axes.get_xaxis().set_visible(False)
axes.get_yaxis().set_visible(False)
fig.savefig('out.png', bbox_inches='tight', pad_inches=0)

get_xaxis()とget_yaxis()が存在しないというエラーが表示されます。なぜそれが起こるのか考えはありますか?
Jacob Malachowski 2017年

axis()オブジェクトを作成し、ax.xaxisとax.yaxisを使用します
ペリゴン2017

'list'オブジェクトに属性 'get_xaxis'がないというエラーが発生しました
HaozheXie19年


3

他の情報なしでプロットのコンテンツを抽出したいlibrosaを使用して視覚化を行っているときに、同じ問題が発生しました。だからこれは私のアプローチです。unutbuの答えは私が仕事をするのにも役立ちます。

    figure = plt.figure(figsize=(500, 600), dpi=1)
    axis = plt.subplot(1, 1, 1)
    plt.axis('off')
    plt.tick_params(axis='both', left='off', top='off', right='off', bottom='off', labelleft='off', labeltop='off',
                    labelright='off', labelbottom='off')

     # your code goes here. e.g: I used librosa function to draw a image
    result = np.array(clip.feature_list['fft'].get_logamplitude()[0:2])
    librosa.display.specshow(result, sr=api.Clip.RATE, x_axis='time', y_axis='mel', cmap='RdBu_r')


    extent = axis.get_window_extent().transformed(figure.dpi_scale_trans.inverted())
    plt.savefig((clip.filename + str("_.jpg")), format='jpg', bbox_inches=extent, pad_inches=0)
    plt.close()

これで正しい方向に進みましたが、2つの問題がありました。1)jupyterノートブックのフォントエラーを回避するために、dpiを1より大きい数値に設定する必要がありました。2)まだ小さな境界線があったため、範囲Bboxを手動でに変更する必要がありextent.get_points()*np.array([[1.1],[.9]])ます。
ボブバックスレイ2017

他の誰かに役立つかもしれない答えを実現してくれてありがとう。
GPrathap 2017

3

Jupyterでこれを行おうとしている人のために

 plt.axis('off')

 spec = plt.imshow

 plt.savefig('spec',bbox_inches='tight',transparent=True, pad_inches=0)

2

上記の回答は余白とパディングの削除に対応していますが、ラベルの削除では機能しませんでした。後でこの質問に出くわした人のために、これがうまくいったことです:

次の場所に保存されている4つの画像からのサブプロットの2x2グリッドが必要であると仮定しますimages

matplotlib.pyplot.figure(figsize = (16,12)) # or whatever image size you require
for i in range(4):
    ax = matplotlib.pyplot.subplot(2,2,i+1)
    ax.axis('off')
    imshow(images[i])
matplotlib.pyplot.savefig(path, bbox_inches='tight')


1

ここのヒントを使用して、境界線も削除しようとしましたが、実際には何も機能しませんでした。いじくり回してみると、Jupyterラボでは、faceolorを変更しても境界線が表示されないことがわかりました(どの色でも白い境界線が削除されました)。お役に立てれば。

def show_num(data):
data = np.rot90(data.reshape((16,16)), k=3)
data = np.fliplr(data)
fig = plt.figure(frameon=False, facecolor='white')
ax = plt.Axes(fig, [0., 0., 1., 1.])
ax.set_axis_off()
fig.add_axes(ax)
ax.imshow(data)
plt.show()

ここに画像の説明を入力してください


1

私にとって、このコードは、matehatunutbu、およびWHZWコードからのフレームと軸なしで入力画像サイズを同様にしました。

fig = plt.figure()
ax = fig.add_subplot(1,1,1)
plt.axis('off')
viridis = cm.get_cmap('gist_gray', 256)
plt.imshow(data, aspect='auto', cmap=viridis)
plt.tight_layout()
plt.savefig(out_file, bbox_inches='tight', transparent=True, pad_inches=0)

ランタイム環境:
Python 3.6.10
Matplotlib 3.2.1
OS Windows 10

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.