Eu tenho uma matriz bidimensional que representa valores de função em posições em um sistema de coordenadas polares. Por exemplo:
import numpy as np
radius = np.linspace(0, 1, 50)
angle = np.linspace(0, 2*np.pi, radius.size)
r_grid, a_grid = np.meshgrid(radius, angle)
data = np.sqrt((r_grid/radius.max())**2
+ (a_grid/angle.max())**2)
Aqui o data
é organizado em uma grade retangular correspondente às coordenadas polares. Quero reorganizar os dados na matriz, de modo que os eixos representem o sistema de coordenadas cartesianas correspondente. O layout antigo versus o novo pode ser visualizado da seguinte maneira:
import matplotlib.pyplot as plt
fig, (ax1, ax2) = plt.subplots(ncols=2, figsize=plt.figaspect(0.5))
ax1.set(title='Polar coordinates', xlabel='Radius', ylabel='Angle')
ax1.pcolormesh(r_grid, a_grid, data)
ax2.set(title='Cartesian coordinates', xlabel='X', ylabel='Y')
x_grid = r_grid * np.cos(a_grid)
y_grid = r_grid * np.sin(a_grid)
ax2.pcolormesh(x_grid, y_grid, data)
Aqui as coordenadas são explicitamente dadas e o gráfico é ajustado de acordo. Quero que os dados sejam reorganizados na própria matriz de dados. Ele deve conter todos os valores, opcionalmente preenchendo com zeros para ajustar a forma (semelhante a scipy.ndimage.rotate(..., reshape=True)
).
Se eu fizer um loop manual sobre as matrizes polares para calcular as coordenadas cartesianas, o resultado conterá regiões vazias que, idealmente, devem ser preenchidas também:
new = np.zeros_like(data)
visits = np.zeros_like(new)
for r, a, d in np.nditer((r_grid, a_grid, data)):
i = 0.5 * (1 + r * np.sin(a)) * new.shape[0]
j = 0.5 * (1 + r * np.cos(a)) * new.shape[1]
i = min(int(i), new.shape[0] - 1)
j = min(int(j), new.shape[1] - 1)
new[i, j] += d
visits[i, j] += 1
new /= np.maximum(visits, 1)
ax2.imshow(new, origin='lower')
Existe uma maneira de conseguir a transformação, evitando regiões vazias na matriz de dados resultante?
fonte
1/r
antes da transformação em coordenadas cartesianas ser computada. Os resultados parecem promissores,y = 0
restam apenas alguns artefatos , então ainda estou analisando.Isso realmente não dá o resultado esperado, mas talvez o ajude a obter uma solução após algumas correções necessárias ...
EDIT: Modificado usando de
np.arctan2
acordo com as sugestões do OP.fonte
np.arctan2
deve-se usar, mas, de qualquer forma, isso introduz enormes discrepâncias em relação às bordas do sistema de coordenadas cartesianas. Na realidade, não há pontos de dados, mas como essa abordagem considera apenas o ponto de dados disponível mais próximo, ele é preenchido enquanto não deveria.skimage.transform.resize
para aumentar a amostra da imagem polar por um determinado fator e usar uma interpolação bilinear o bicúbica e, em seguida, usar essa abordagem para fazer a transformação. Você terminaria com uma transformação mais precisa.Você pode fazer um loop na matriz cartesiana, transformando cada ponto da grade em coordenadas polares e aproximando o valor da função por interpolação a partir dos dados da grade polar. Você ainda pode deixar as regiões de canto em branco, por falta de dados suficientes.
Eu não acho que exista uma maneira melhor, a menos que você tenha acesso à função original.
fonte