Подтвердить что ты не робот

Как увеличить часть изображения и вставить в тот же участок в matplotlib

Я хотел бы увеличить часть данных/изображения и нарисовать его на одном и том же рисунке. Это похоже на эту цифру.

zoomed plot

Возможно ли вставить часть увеличенного изображения внутри одного и того же участка. Я думаю, что можно нарисовать еще одну фигуру с подзаголовком, но она рисует две разные фигуры. Я также читал, чтобы добавить патч для вставки прямоугольника/круга, но не уверен, полезно ли вставлять часть изображения в фигуру. Я в основном загружаю данные из текстового файла и строю его с помощью простых команд графика, показанных ниже.

Я нашел один пример из галереи изображений matplotlib здесь, но не знаю, как это работает. Ваша помощь очень ценится.

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

Ответ 1

Воспроизведение с помощью исполняемого кода является одним из самые быстрые способы изучения Python.

Итак, давайте начнем с кода из галереи примеров matplotlib.

Учитывая комментарии в коде, кажется, что код разбит на 4 основные строфы. Первая строфа генерирует некоторые данные, вторая строфа генерирует основной сюжет, третья и четвертая строфы создают оси вставки.

Мы знаем, как генерировать данные и строить сюжет, поэтому давайте сосредоточимся на третьей строфе:

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

Запустите script:

python test.py

Вы увидите, что вставка "Вероятность" перемещена влево. Таким образом, функция axes контролирует размещение вставки. Если вы сыграете еще немного с цифрами, вы поймете, что (.35,.6) является расположение нижнего левого угла вставки и (.2,.2) - это ширина и высота вставки. Числа идут от 0 до 1 и (0,0) - это место, расположенное на нижний левый угол рисунка.

Хорошо, теперь мы готовим. На следующей строке мы имеем:

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

Вы можете распознать это как команду matplotlib для рисования гистограммы, но если нет, изменение числа 400 до, скажем, 10, приведет к созданию изображения с большим chunkier histogram, поэтому снова, играя с номерами, которые вы скоро выясните что эта линия имеет какое-то отношение к изображению внутри вставки.

Здесь вы можете вызвать semilogx(data[3:8,1],data[3:8,2]).

Линия title('Probability') явно генерирует текст над вставкой.

Наконец, мы переходим к setp(a, xticks=[], yticks=[]). Нет чисел, с которыми можно играть, поэтому, если мы просто прокомментируем всю строку, поместив # в начало строки:

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

Перезапустите script. Ой! теперь на вставных осях есть много меток и меток. Хорошо. Итак, теперь мы знаем, что setp(a, xticks=[], yticks=[]) удаляет отметки и метки меток из осей a.

Теперь, теоретически, у вас достаточно информации для применения этого кода к вашей проблеме. Но есть еще один потенциальный камень преткновения: пример matplotlib использует from pylab import * тогда как вы используете import matplotlib.pyplot as plt.

Часто задаваемые вопросы о matplotlib говорит import matplotlib.pyplot as plt это рекомендуемый способ использования matplotlib при написании сценариев, в то время как from pylab import * предназначен для использования в интерактивных сеансах. Таким образом, вы делаете это правильно, (хотя я бы рекомендовал использовать import numpy as np вместо from numpy import * тоже).

Итак, как мы преобразуем пример matplotlib для работы с import matplotlib.pyplot as plt?

Выполнение преобразования требует некоторого опыта работы с matplotlib. Как правило, вы просто добавьте plt. перед голой именами, такими как axes и setp, но иногда функция исходит из numpy, а иногда вызов должен поступать из осей объект, а не из модуля 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()

Ответ 2

Самый простой способ - объединить "zoomed_inset_axes" и "mark_inset", описание которых и связанные примеры можно найти здесь: Обзор инструментария AxesGrid

enter image description here

Ответ 3

Самый приятный способ, которым я это знаю, - использовать mpl_toolkits.axes_grid1.inset_locator (часть matplotlib).

Здесь есть отличный пример с исходным кодом: enter image description herehttps://github.com/NelleV/jhepc/tree/master/2013/entry10

Ответ 4

Основные шаги для увеличения части фигуры с помощью 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()

введите описание изображения здесь