web-dev-qa-db-ja.com

画像の一部をズームしてmatplotlibの同じプロットに挿入する方法

データ/画像の一部をズームして、同じ図の中にプロットしたいと思います。この図のように見えます。

zoomed plot

同じプロット内にズーム画像の一部を挿入することは可能ですか?サブプロットで別の図を描くことは可能だと思いますが、2つの異なる図を描きます。長方形/円を挿入するパッチを追加することも読みましたが、画像の一部を図に挿入することが有用かどうかはわかりません。基本的に、テキストファイルからデータを読み込み、以下に示す簡単なプロットコマンドを使用してプロットします。

Matplotlibイメージギャラリーから関連する例を1つ見つけました here ですが、どのように機能するかはわかりません。あなたの助けは大歓迎です。

from numpy import *
import os
import matplotlib.pyplot as plt
data = loadtxt(os.getcwd()+txtfl[0], skiprows=1)
fig1 = plt.figure()
ax1 = fig1.add_subplot(111)
ax1.semilogx(data[:,1],data[:,2])
plt.show()
43
Elect28

実行可能なコードで遊ぶことは、Pythonを学ぶ最も速い方法の1つです。

matplotlibサンプルギャラリーのコード から始めましょう。

コード内のコメントを考えると、コードは4つの主要なスタンザに分かれているようです。最初のスタンザはいくつかのデータを生成し、2番目のスタンザはメインプロットを生成し、3番目と4番目のスタンザは挿入軸を作成します。

データを生成してメインプロットをプロットする方法はわかっているので、3番目のスタンザに注目しましょう。

_a = axes([.65, .6, .2, .2], axisbg='y')
n, bins, patches = hist(s, 400, normed=1)
title('Probability')
setp(a, xticks=[], yticks=[])
_

サンプルコードを、たとえば_test.py_という新しいファイルにコピーします。

_.65_を_.3_に変更するとどうなりますか?

_a = axes([.35, .6, .2, .2], axisbg='y')
_

スクリプトを実行します。

_python test.py
_

「確率」インセットが左に移動していることがわかります。したがって、axes関数はインセットの配置を制御します。数字を使ってもう少し遊ぶと、(。35、.6)がインセットの左下隅の位置であり、(。2、.2)がインセットの幅と高さであることがわかります。番号は0から1までで、(0,0)は図の左下隅にあります。

さて、今私たちは料理をしています。次の行に進みます:

_n, bins, patches = hist(s, 400, normed=1)
_

これは ヒストグラムを描画するためのmatplotlibコマンド として認識するかもしれませんが、そうでない場合、400をたとえば10に変更すると、より大きなヒストグラムの画像が生成されます。この行がはめ込み内の画像と関係があることがすぐにわかります。

ここでsemilogx(data[3:8,1],data[3:8,2])を呼び出したいでしょう。

title('Probability')は、明らかにインセットの上にテキストを生成します。

最後にsetp(a, xticks=[], yticks=[])に行きます。遊ぶべき数字はないので、行の先頭に_#_を置いて行全体をコメントアウトするとどうなりますか:

_# setp(a, xticks=[], yticks=[])
_

スクリプトを再実行します。ああ!挿入軸に目盛りと目盛りラベルがたくさんあります。いいよこれで、setp(a, xticks=[], yticks=[])が軸aから目盛りとラベルを削除することがわかりました。

さて、理論的には、このコードを問題に適用するのに十分な情報があります。しかし、もう1つの潜在的な障害があります。matplotlibの例では_from pylab import *_を使用していますが、_import matplotlib.pyplot as plt_を使用しています。

matplotlib FAQ は、スクリプトを記述するときに_import matplotlib.pyplot as plt_がmatplotlibを使用するための推奨される方法であり、_from pylab import *_は対話型セッションで使用するためのものです。したがって、あなたはそれを正しい方法で行っています(ただし、_import numpy as np_の代わりに_from numpy import *_を使用することをお勧めします)。

では、matplotlibの例を_import matplotlib.pyplot as plt_で実行するように変換するにはどうすればよいですか?

変換を行うには、matplotlibである程度の経験が必要です。一般に、axessetpのような裸の名前の前に_plt._を追加するだけですが、関数はnumpyから来ることがあり、呼び出しはAxesオブジェクトからではなく、モジュールpltから。これらすべての機能がどこから来たのかを知るには経験が必要です。 「matplotlib」と一緒に関数の名前をググリングすることは役立ちます。サンプルコードを読むことで経験を積むことができますが、簡単なショートカットはありません。

したがって、変換されたコードは

_ax2 = plt.axes([.65, .6, .2, .2], axisbg='y')
ax2.semilogx(t[3:8],s[3:8])
plt.setp(ax2, xticks=[], yticks=[])
_

そして、次のようにコードで使用できます。

_from numpy import *
import os
import matplotlib.pyplot as plt
data = loadtxt(os.getcwd()+txtfl[0], skiprows=1)
fig1 = plt.figure()
ax1 = fig1.add_subplot(111)
ax1.semilogx(data[:,1],data[:,2])

ax2 = plt.axes([.65, .6, .2, .2], axisbg='y')
ax2.semilogx(data[3:8,1],data[3:8,2])
plt.setp(ax2, xticks=[], yticks=[])

plt.show()
_
30
unutbu

最も簡単な方法は、「zoomed_inset_axes」と「mark_inset」を組み合わせることです。その説明と関連例は、ここにあります: AxesGridツールキットの概要

enter image description here

26
kevin

これを行うために知っている最も良い方法は、mpl_toolkits.axes_grid1.inset_locator(matplotlibの一部)を使用することです。

ここにソースコードの素晴らしい例があります: enter image description herehttps://github.com/NelleV/jhepc/tree/master/2013/entry1

22
David Ketcheson

Matplotlibを使用してFigureの一部を拡大する基本的な手順

import numpy as np
from matplotlib import pyplot as plt

# Generate the main data
X = np.linspace(-6, 6, 1024)
Y = np.sinc(X)

# Generate data for the zoomed portion
X_detail = np.linspace(-3, 3, 1024)
Y_detail = np.sinc(X_detail)

# plot the main figure
plt.plot(X, Y, c = 'k')  

 # location for the zoomed portion 
sub_axes = plt.axes([.6, .6, .25, .25]) 

# plot the zoomed portion
sub_axes.plot(X_detail, Y_detail, c = 'k') 

# insert the zoomed figure
# plt.setp(sub_axes)

plt.show()

enter image description here

7
Amjad