2017-03-10 16 views
2

これは、ベースマップを使用してGeogtiffファイルからデータをプロットするスクリプトです。データはカテゴリに分類され、このドメインには13のカテゴリがあります。問題は、一部のカテゴリが1つの色にまとめられているため、一部の解像度が失われることです。
残念ながら、私はこれを修正する方法がわかりません。私はplt.cm.get_cmpがディスクリートデータセットのほうが優れていると読んでいますが、残念ながらそれを働かせることはできませんでした。ここでColormapがデータを正しく分類していません

gtif = 'some_dir' 

ds = gdal.Open(gtif) 
data = ds.ReadAsArray() 
gt = ds.GetGeoTransform() 
proj = ds.GetProjection() 
xres = gt[1] 
yres = gt[5] 

xmin = gt[0] + xres 
xmax = gt[0] + (xres * ds.RasterXSize) - xres 
ymin = gt[3] + (yres * ds.RasterYSize) + yres 
ymax = gt[3] - yres 
xy_source = np.mgrid[xmin:xmax+xres:xres, ymax+yres:ymin:yres] 
ds = None 

fig2 = plt.figure(figsize=[12, 11]) 
ax2 = fig2.add_subplot(111) 
ax2.set_title("Land use plot") 
bm2 = Basemap(ax=ax2,projection='cyl',llcrnrlat=ymin,urcrnrlat=ymax,llcrnrlon=xmin,urcrnrlon=xmax,resolution='l') 
bm2.drawcoastlines(linewidth=0.2) 
bm2.drawcountries(linewidth=0.2) 

data_new=np.copy(data) 
data_new[data_new==255] = 0 

nbins = np.unique(data_new).size 
cb =plt.cm.get_cmap('jet', nbins+1) 
img2 =bm2.imshow(np.flipud(data_new), cmap=cb) 
ax2.set_xlim(3, 6) 
ax2.set_ylim(50,53) 
plt.show() 

labels = [str(i) for i in np.unique(data_new)] 
cb2=bm2.colorbar(img2, "right", size="5%", pad='3%', label='NOAH Land Use Category') 
cb2.set_ticklabels(labels) 
cb2.set_ticks(np.unique(data_new)) 

ドメイン内で発見されたカテゴリ(番号クラス)は次のとおりです。ここでは任意の助け

np.unique(data_new) 

array([ 0, 1, 4, 5, 7, 10, 11, 12, 13, 14, 15, 16, 17], dtype=uint8) 

本当にありがとうございましたが。 ミスマッチを示す出力イメージも添付しました。 (動作していません)

答えて

1

まず、このカラーマップの問題は、ベースマップの使用に依存しません。したがって、以下は、任意のマットプロット図に適用可能です。

ここで問題となるのは、n値からカラーマップを作成すると、それらの値がカラーマップ範囲に均等に分配されることです。したがって、イメージの一部の値はカラーマップ内の同じ色範囲に入ります。

これを防ぐには、以下に示すようにカテゴリの初期数でカラーマップを生成することができます。

enter image description here

import matplotlib.pyplot as plt 
import numpy as np 
import matplotlib.colors 

# generate some data 
data = np.array([ 0, 1, 4, 5, 7, 10]*8) 
np.random.shuffle(data) 
data = data.reshape((8,6)) 

# generate colormap and norm 
unique = np.unique(data) 
vals = np.arange(int(unique.max()+1))/float(unique.max()) 
cols = plt.cm.jet(vals) 
cmap = matplotlib.colors.ListedColormap(cols, int(unique.max())+1) 
norm=matplotlib.colors.Normalize(vmin=-0.5, vmax=unique.max()+0.5) 


fig, ax = plt.subplots(figsize=(5,5)) 
im = ax.imshow(data, cmap=cmap, norm=norm) 
for i in range(data.shape[0]): 
    for j in range(data.shape[1]): 
     ax.text(j,i,data[i,j], color="w", ha="center", va="center") 

cb = fig.colorbar(im, ax=ax, norm=norm) 
cb.set_ticks(unique) 

plt.show() 


次のようにこれは、画像内に存在しない色を除外するように拡張することができます:迅速な返信用

enter image description here

import matplotlib.pyplot as plt 
import numpy as np 
import matplotlib.colors 

# generate some data 
data = np.array([ 0, 1, 4, 5, 7, 10]*8) 
np.random.shuffle(data) 
data = data.reshape((8,6)) 

unique, newdata = np.unique(data, return_inverse=1) 
newdata = newdata.reshape(data.shape) 

# generate colormap and norm 
new_unique = np.unique(newdata) 
vals = np.arange(int(new_unique.max()+1))/float(new_unique.max()) 
cols = plt.cm.jet(vals) 
cmap = matplotlib.colors.ListedColormap(cols, int(new_unique.max())+1) 
norm=matplotlib.colors.Normalize(vmin=-0.5, vmax=new_unique.max()+0.5) 

fig, ax = plt.subplots(figsize=(5,5)) 
im = ax.imshow(newdata, cmap=cmap, norm=norm) 
for i in range(newdata.shape[0]): 
    for j in range(newdata.shape[1]): 
     ax.text(j,i,data[i,j], color="w", ha="center", va="center") 

cb = fig.colorbar(im, ax=ax, norm=norm) 
cb.ax.set_yticklabels(unique) 

plt.show() 
+0

ありがとうを!これは動作しますが、唯一の問題は、入れ子にされたforループが、私が持っている非常に大きなデータセット(数千ポイント)が遅いことです。非常に大きなデータセットに対してこれを最適化する方法はありますか? – user2013373

+0

私はループを使用するより効率的なバージョンの答えを編集しました。 – ImportanceOfBeingErnest

+0

ありがとう!私はループを避けるために働くと思っていたようなものです。よい一週間を! – user2013373