Контурни неправилни данни в многоъгълник

Трябва да създам запълнени контурни графики на данни за температурата на морската повърхност (SST) в рамките на многоъгълник, но не съм сигурен кой е най-добрият начин да направя това. Имам три 1D масива, съдържащи данни за X, Y и SST, които начертавам, като използвам следното, за да създам прикачения график:

p=PatchCollection(mypatches,color='none', alpha=1.0,edgecolor="purple",linewidth=2.0)
levels=np.arange(SST.min(),SST.max(),0.2)
datamap=mymap.scatter(x,y,c=SST, s=55, vmin=-2,vmax=3,alpha=1.0)

Бих искал да мога да начертая тези данни като запълнени контури (contourf вместо scatter), които са ограничени (подрязани) в рамките на границите на полигона (лилавата линия). Предложенията как да се постигне това се оценяват високо.

въведете описание на изображението тук

Актуализация: Първоначално бях пробвал griddata, но не можах да я накарам да работи правилно. Въпреки това, въз основа на отговора, предоставен от @eatHam, реших да опитам отново. Не можах да накарам scipy griddata да работи, тъй като продължаваше да виси в решетката, когато избирах метода „cubic“, но когато превключих на matplotlib.mlab.griddata и използвах „линейна“ интерполация, тя работи. Предложението за маскиране на границите предостави много грубо и не толкова точно решение, колкото бих предпочел. Изображение, показващо решението с използване на маскирано изрязване

Търсих опции как да изрязвам контури в matplotlib и намерих отговор от @pelson на този връзка. Опитах предложеното решение, подразбиращо се в: „Самият набор от контури няма метод set_clip_path, но можете да преминете през всяка от колекциите от контури и да зададете съответните им пътеки за изрязване“. Моето ново и окончателно решение изглежда така (вижте графиката по-долу):

  p=PatchCollection(mypatches,color='none', alpha=1.0,edgecolor="purple",linewidth=2.0)
  levels=np.arange(SST.min(),SST.max(),0.2)
  grid_x, grid_y = np.mgrid[x.min()-0.5*(x.min()):x.max()+0.5*(x.max()):200j,
                          y.min()-0.5*(y.min()):y.max()+0.5*(y.max()):200j]
  grid_z = griddata(x,y,SST,grid_x,grid_y)

  cs=mymap.contourf(grid_x, grid_y, grid_z)

  for poly in mypatches:
      for artist in ax.get_children():
          artist.set_clip_path(poly)

      ax.add_patch(poly)
  mymap.drawcountries()
  mymap.drawcoastlines()
  mymap.fillcontinents(color='lightgrey',lake_color='none')
  mymap.drawmapboundary(fill_color='none')

Това решение може също да бъде подобрено по-специално по отношение на екстраполирането на крайните ръбове на север. Оценяват се предложения за това как наистина да се „попълни“ целият многоъгълник. Също така бих искал да разбера защо mlab работи, а scipy не.

Окончателно решение, показващо изрязани контури с помощта на set_clip_path


person Trond Kristiansen    schedule 12.09.2013    source източник
comment
Какви методи за интерполация сте пробвали?   -  person tacaswell    schedule 13.09.2013
comment
@tcaswell Моля, вижте моя актуализиран отговор   -  person Trond Kristiansen    schedule 13.09.2013
comment
scipy и mlab версията на griddata и различни методи, така че това не е изненадващо. Мисля, че проблемът с интерполирането извън данните, които имате, е по-фундаментален проблем и ще включва съмнителни методи за заобикаляне;)   -  person tacaswell    schedule 13.09.2013


Отговори (1)


Бих интерполирал данните с помощта на scipy. мрежови данни. Можете да зададете регион извън вашия район (mypatches) на np.nan. И след това просто използвайте pyplot.contour, за да го начертаете.

import numpy as np
import matplotlib.pyplot as plt
from scipy.interpolate import griddata

def sst_data(x, y):
    return x*(1-x)*np.cos(4*np.pi*x) * np.sin(4*np.pi*y**2)**2

                         #replace with ...
x = np.random.rand(1000) #... your x
y = np.random.rand(1000) #... your y
sst = sst_data(x, y)     #... your sst

# interpolate to a grid
grid_x, grid_y = np.mgrid[0:1:100j, 0:1:200j] 
grid_z = griddata((x,y), sst, (grid_x, grid_y), method='cubic')

# mask out the area outside of your region
nr, nc = grid_z.shape
grid_z[-nr//3:, -nc//3:] = np.nan

plt.contourf(grid_x, grid_y, grid_z)

plt.show()

въведете описание на изображението тук

РЕДАКТИРАНЕ: Променено име на променлива в извикването на plt.contourf() (беше ..(grid_z, grid_y, grid_z))

person thorink    schedule 13.09.2013
comment
Вашето предложение ме насочи към правилния път, така че приех отговора ви. - person Trond Kristiansen; 13.09.2013