简体   繁体   English

如何缩放图像的一部分并插入matplotlib中的相同图中

[英]How to zoomed a portion of image and insert in the same plot in matplotlib

I would like to zoom a portion of data/image and plot it inside the same figure. 我想缩放一部分数据/图像并将其绘制在同一图中。 It looks something like this figure. 它看起来像这个数字。

缩放的情节

Is it possible to insert a portion of zoomed image inside the same plot. 是否可以在同一绘图中插入一部分缩放图像。 I think it is possible to draw another figure with subplot but it draws two different figures. 我认为可以用子图绘制另一个图,但它绘制了两个不同的数字。 I also read to add patch to insert rectangle/circle but not sure if it is useful to insert a portion of image into the figure. 我还读过添加补丁来插入矩形/圆形,但不确定将图像的一部分插入图中是否有用。 I basically load data from the text file and plot it using a simple plot commands shown below. 我基本上从文本文件加载数据并使用下面显示的简单绘图命令绘制它。

I found one related example from matplotlib image gallery here but not sure how it works. 我在这里找到了matplotlib图片库中的一个相关示例,但不确定它是如何工作的。 Your help is much appreciated. 非常感谢您的帮助。

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()

Playing with runnable code is one of the fastest ways to learn Python. 使用可运行代码是学习Python的最快方法之一。

So let's start with the code from the matplotlib example gallery . 所以让我们从matplotlib示例库中代码开始。

Given the comments in the code, it appears the code is broken up into 4 main stanzas. 鉴于代码中的注释,似乎代码被分解为4个主要节。 The first stanza generates some data, the second stanza generates the main plot, the third and fourth stanzas create the inset axes. 第一节生成一些数据,第二节生成主图,第三节和第四节创建插入轴。

We know how to generate data and plot the main plot, so let's focus on the third stanza: 我们知道如何生成数据并绘制主要情节,所以让我们关注第三节:

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

Copy the example code into a new file, called, say, test.py . 将示例代码复制到一个名为test.py的新文件中。

What happens if we change the .65 to .3 ? 如果我们将.65更改为.3会发生什么?

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

Run the script: 运行脚本:

python test.py

You'll find the "Probability" inset moved to the left. 你会发现“概率”插图向左移动。 So the axes function controls the placement of the inset. 因此, axes功能控制插入的位置。 If you play some more with the numbers you'll figure out that (.35, .6) is the location of the lower left corner of the inset, and (.2, .2) is the width and height of the inset. 如果你用数字玩更多,你会发现(.35,.6)是插图左下角的位置,而(。2,.2)是插图的宽度和高度。 The numbers go from 0 to 1 and (0,0) is the located at the lower left corner of the figure. 数字从0到1,(0,0)位于图的左下角。

Okay, now we're cooking. 好的,现在我们正在做饭。 On to the next line we have: 到下一行,我们有:

n, bins, patches = hist(s, 400, normed=1)

You might recognize this as the matplotlib command for drawing a histogram , but if not, changing the number 400 to, say, 10, will produce an image with a much chunkier histogram, so again by playing with the numbers you'll soon figure out that this line has something to do with the image inside the inset. 您可能会将此识别为用于绘制直方图matplotlib命令 ,但如果不是,将数字400更改为,例如10,将生成具有更粗的直方图的图像,因此再次通过使用您很快就会发现的数字这条线与插图内的图像有关。

You'll want to call semilogx(data[3:8,1],data[3:8,2]) here. 你想在这里调用semilogx(data[3:8,1],data[3:8,2])

The line title('Probability') obviously generates the text above the inset. title('Probability')显然会在插图上方生成文本。

Finally we come to setp(a, xticks=[], yticks=[]) . 最后我们来到setp(a, xticks=[], yticks=[]) There are no numbers to play with, so what happens if we just comment out the whole line by placing a # at the beginning of the line: 没有数字可以使用,所以如果我们只是通过在行的开头放置一个#注释整行,会发生什么:

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

Rerun the script. 重新运行脚本。 Oh! 哦! now there are lots of tick marks and tick labels on the inset axes. 现在插入轴上有很多刻度线和刻度标签。 Fine. 精细。 So now we know that setp(a, xticks=[], yticks=[]) removes the tick marks and labels from the axes a . 所以现在我们知道setp(a, xticks=[], yticks=[])从轴a删除刻度线和标签。

Now, in theory you have enough information to apply this code to your problem. 现在,从理论上讲,您有足够的信息将此代码应用于您的问题。 But there is one more potential stumbling block: The matplotlib example uses from pylab import * whereas you use import matplotlib.pyplot as plt . 但还有一个潜在的障碍:matplotlib示例使用from pylab import *而您使用import matplotlib.pyplot as plt

The matplotlib FAQ says import matplotlib.pyplot as plt is the recommended way to use matplotlib when writing scripts, while from pylab import * is for use in interactive sessions. matplotlib常见问题解答import matplotlib.pyplot as plt是在编写脚本时使用matplotlib的推荐方法,而from pylab import *则用于交互式会话。 So you are doing it the right way, (though I would recommend using import numpy as np instead of from numpy import * too). 所以你正在以正确的方式做到这一点,(虽然我建议使用import numpy as np而不是from numpy import * )。

So how do we convert the matplotlib example to run with import matplotlib.pyplot as plt ? 那么我们如何将matplotlib示例转换为使用import matplotlib.pyplot as plt运行?

Doing the conversion takes some experience with matplotlib. 进行转换需要matplotlib的一些经验。 Generally, you just add plt. 通常,您只需添加plt. in front of bare names like axes and setp , but sometimes the function come from numpy, and sometimes the call should come from an axes object, not from the module plt . 在诸如axessetp类的裸名称之前,但有时函数来自numpy,有时调用应来自轴对象,而不是来自模块plt It takes experience to know where all these functions come from. 需要经验才能知道所有这些功能的来源。 Googling the names of functions along with "matplotlib" can help. 使用“matplotlib”搜索函数名称可以提供帮助。 Reading example code can builds experience, but there is no easy shortcut. 阅读示例代码可以构建体验,但没有简单的快捷方式。

So, the converted code becomes 因此,转换后的代码变为

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

And you could use it in your code like this: 你可以在你的代码中使用它,如下所示:

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()

The simplest way is to combine "zoomed_inset_axes" and "mark_inset", whose description and related examples could be found here: Overview of AxesGrid toolkit 最简单的方法是组合“zoomed_inset_axes”和“mark_inset”,其描述和相关示例可在此处找到: AxesGrid工具包概述

在此输入图像描述

The nicest way I know of to do this is to use mpl_toolkits.axes_grid1.inset_locator (part of matplotlib). 我知道要做的最好的方法是使用mpl_toolkits.axes_grid1.inset_locator(matplotlib的一部分)。

There is a great example with source code here: 这里有一个很好的源代码示例: 在此输入图像描述 https://github.com/NelleV/jhepc/tree/master/2013/entry10 https://github.com/NelleV/jhepc/tree/master/2013/entry10

The basic steps to zoom up a portion of a figure with matplotlib 使用matplotlib缩放图形的一部分的基本步骤

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()

在此输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM