Преобразуйте фигуру matplotlib в массив с одинаковой формой - PullRequest
0 голосов
/ 16 апреля 2019

У меня есть изображение 256x256, и я хочу иметь возможность построить линию регрессии через точки. Для этого я преобразовал изображение в диаграмму рассеяния, а затем попытался преобразовать диаграмму рассеяния обратно в массив. Тем не менее, преобразование обратно в массив Numpy сделало массив NumPy 480x640.

Может ли кто-нибудь объяснить мне, почему форма меняется, в основном, почему это уже не квадратное изображение, и если есть какое-либо преобразование, чтобы исправить это?

Создание моих точек x и y из двоичного изображения

imagetile = a[2]
x, y = np.where(imagetile>0)
imagetile.shape

Выход: (256 л, 256 л)

Версия 1

from numpy import polyfit
from numpy import polyval

imagetile = a[2]
x, y = np.where(imagetile>0)

from numpy import polyfit
from numpy import polyval

p2 = polyfit(x, y, 2)

fig = plt.figure()
ax = fig.add_axes([0.,0.,1.,1.])
xp = np.linspace(0, 256, 256)
plt.scatter(x, y)
plt.xlim(0,256)
plt.ylim(0,256)
plt.plot(xp, polyval(p2, xp), "b-")
plt.show()

fig.canvas.draw()
X = np.array(fig.canvas.renderer._renderer)
X.shape

Выход: (480 л, 640 л, 4 л)

Версия 2

def fig2data ( fig ):
    """
    @brief Convert a Matplotlib figure to a 4D numpy array with RGBA channels and return it
    @param fig a matplotlib figure
    @return a numpy 3D array of RGBA values
    """
    # draw the renderer
    fig.canvas.draw ( )

    # Get the RGBA buffer from the figure
    w,h = fig.canvas.get_width_height()
    buf = np.fromstring ( fig.canvas.tostring_argb(), dtype=np.uint8 )
    buf.shape = ( w, h,4 )

    # canvas.tostring_argb give pixmap in ARGB mode. Roll the ALPHA channel to have it in RGBA mode
    buf = np.roll ( buf, 3, axis = 2 )
    return buf

figure = matplotlib.pyplot.figure(  )
plot   = figure.add_subplot ( 111 )


x, y = np.where(imagetile>0)
p2 = polyfit(x, y, 2)
plt.scatter(x, y)
plt.xlim(0,256)
plt.ylim(0,256)
plt.plot(xp, polyval(p2, xp), "b-")

data = fig2data(figure)
data.shape

Выход: (640 л, 480 л, 4 л)

Спасибо

1 Ответ

1 голос
/ 16 апреля 2019

Если вы вызываете matplotlib.pyplot.figure без установки аргумента figsize, он принимает форму по умолчанию (цитата из документации):

figsize: (float,float), необязательно, по умолчанию: None ширина, высота в дюймах.Если не указан, по умолчанию используется rcParams ["figure.figsize"] = [6.4, 4.8].

Итак, вы можете установить форму, выполнив

matplotlib.pyplot.figure(figsize=(2.56,2.56))

Не знаякак выглядят ваши данные, я думаю, что ваш подход довольно окольный, поэтому я предлагаю что-то вроде этого:

import numpy as np
import matplotlib.pyplot as plt

# generating simulated polynomial data:
arr = np.zeros((256, 256))
par = [((a-128)**2, a) for a in range(256)]
par = [p for p in par if p[0]<255]
arr[zip(*par)] = 1

x, y = np.where(arr>0)
p2 = np.polyfit(y, x, 2)
xp = np.linspace(0,256,256)

plt.imshow(arr) # show the image, rather than the conversion to datapoints

p = np.poly1d(p2) # recommended in the documentation for np.polyfit

plt.plot(xp, p(xp))

plt.ylim(0,256)
plt.xlim(0,256)

plt.show()

ссылка на документацию np.polyfit

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...