2014-07-15 172 views
-1

我想知道是否可以使用Matplotlib做一個可視化。用Matplotlib/Python繪製模糊線條

enter image description here

另一種觀點:

enter image description here

來源:http://dl.acm.org/citation.cfm?id=1961832

哪個這些圖片做什麼,我希望做的是兩個可視化結合起來。酮(背景)是一個簡單的情節可以與進行imshow令pColorpcolormesh,但其他人使用一個網格,其模糊(在瓦特因子)確定一些特性的質地,在這種情況下,不確定性。我不知道如何做的是繪製不同模糊的不同線條。對於每個像素,我有一個不確定性,我應該在這個像素中繪製一條線,其中不確定性表示爲線條模糊。

我不知道如何與Matplotlib做到這一點後者(繪製模糊的線)。

任何幫助,將不勝感激。 預先感謝您。

+0

我不知道如果我正確地得到您的問題。是否可以通過使用pcolormesh進行熱圖來解決,然後使用與您的不確定性相對應的alpha值繪製黑色線條來形成網格? – Christoph

+0

我沒有看到任何阻止你這樣做的事情。讓所有的線路匹配起來會有點麻煩,但是有工具可以完成所有這些,我已經使用了它們。 – will

+0

是的,我相信我提出的解決方案可以發揮作用。如果我正在解決正確的問題,我不太確定。 – Christoph

回答

5

那麼這裏是我迄今爲止 - 我去了一個切點複製fig. 2

明天更新。 (上半場僅僅是創建一些數據)

from mpl_toolkits.mplot3d import Axes3D 
from matplotlib import cm 
import matplotlib.pyplot as plt 
from mpl_toolkits.mplot3d import proj3d 
import numpy as np 
import matplotlib.gridspec as gridspec 
import matplotlib 

def smooth1d(x, window_len): 
    s=np.r_[2*x[0]-x[window_len:1:-1],x,2*x[-1]-x[-1:-window_len:-1]] 
    w = np.hanning(window_len) 
    y=np.convolve(w/w.sum(),s,mode='same') 
    return y[window_len-1:-window_len+1] 

def smooth2d(A, sigma=3): 
    window_len = max(int(sigma), 3)*2+1 
    A1 = np.array([smooth1d(x, window_len) for x in np.asarray(A)]) 
    A2 = np.transpose(A1) 
    A3 = np.array([smooth1d(x, window_len) for x in A2]) 
    A4 = np.transpose(A3) 

    return A4 

class BaseFilter(object): 
    def prepare_image(self, src_image, dpi, pad): 
     ny, nx, depth = src_image.shape 
     #tgt_image = np.zeros([pad*2+ny, pad*2+nx, depth], dtype="d") 
     padded_src = np.zeros([pad*2+ny, pad*2+nx, depth], dtype="d") 
     padded_src[pad:-pad, pad:-pad,:] = src_image[:,:,:] 

     return padded_src#, tgt_image 

    def get_pad(self, dpi): 
     return 0 

    def __call__(self, im, dpi): 
     pad = self.get_pad(dpi) 
     padded_src = self.prepare_image(im, dpi, pad) 
     tgt_image = self.process_image(padded_src, dpi) 
     return tgt_image, -pad, -pad 

class GaussianFilter(BaseFilter): 
    "simple gauss filter" 
    def __init__(self, sigma, alpha=0.5, color=None): 
     self.sigma = sigma 
     self.alpha = alpha 
     if color is None: 
      self.color=(0, 0, 0) 
     else: 
      self.color=color 

    def get_pad(self, dpi): 
     return int(self.sigma*3/72.*dpi) 


    def process_image(self, padded_src, dpi): 
     #offsetx, offsety = int(self.offsets[0]), int(self.offsets[1]) 
     tgt_image = np.zeros_like(padded_src) 
     aa = smooth2d(padded_src[:,:,-1]*self.alpha, 
         self.sigma/72.*dpi) 
     tgt_image[:,:,-1] = aa 
     tgt_image[:,:,:-1] = self.color 
     return tgt_image 


from matplotlib.artist import Artist 

class FilteredArtistList(Artist): 
    """ 
    A simple container to draw filtered artist. 
    """ 
    def __init__(self, artist_list, filter): 
     self._artist_list = artist_list 
     self._filter = filter 
     Artist.__init__(self) 

    def draw(self, renderer): 
     renderer.start_rasterizing() 
     renderer.start_filter() 
     for a in self._artist_list: 
      a.draw(renderer) 
     renderer.stop_filter(self._filter) 
     renderer.stop_rasterizing() 





##Create the landscape 
from noise import snoise2 

def boxOnSurface(rect, X,Y,Z): 
    #Make rectangle of indicies to draw. Left the four loops expanded for clarity. Otherwise it's fairly ugly. 
    rXs, rYs, rZs = [],[],[] 

    for j in range(rect[0][1], rect[1][1]): 
    i = rect[0][0] 

    rXs.append(X[i][j]) 
    rYs.append(Y[i][j]) 
    rZs.append(Z[i][j]) 

    for i in range(rect[0][0], rect[1][0]): 
    j = rect[1][1] 

    rXs.append(X[i][j]) 
    rYs.append(Y[i][j]) 
    rZs.append(Z[i][j]) 

    for j in range(rect[1][1], rect[0][1], -1): 
    i = rect[1][0] 

    rXs.append(X[i][j]) 
    rYs.append(Y[i][j]) 
    rZs.append(Z[i][j]) 

    for i in range(rect[1][0], rect[0][0]-1, -1): 
    j = rect[0][1] 

    rXs.append(X[i][j]) 
    rYs.append(Y[i][j]) 
    rZs.append(Z[i][j]) 

    return rXs, rYs, rZs, [np.mean(rXs), np.mean(rYs), np.mean(rZs)] 



octaves = 4 
freq = octaves * 100 


xs, ys = np.linspace(0.0, 100.0, 100), np.linspace(0.0, 100.0, 100) 
X,Y = np.meshgrid(xs,ys) 

Z1 = np.zeros(X.shape) 


for i,x in enumerate(xs): 
    for j,y in enumerate(ys): 
    Z1[i][j] = int(snoise2(x/freq, y/freq, octaves) * 127.0 + 128.0) 



# get some different colours for the surface. 
faceValues = np.zeros(X.shape) 

noise = [] 

for i,x in enumerate(xs): 
    for j,y in enumerate(ys): 
    faceValues[i][j] = snoise2(4*x/freq, 4*y/freq, octaves) 

jet = cm.get_cmap("jet") 
faceColours = [] 


for i,x in enumerate(xs): 
    faceColours.append([]) 
    for j,y in enumerate(ys): 
    normalised = (faceValues[i][j] - faceValues.min())/(faceValues.max() - faceValues.min()) 
    faceColours[i].append(jet(normalised)) 
    faceValues[i][j] = normalised 




fig = plt.figure() 
miniPlotCount = 5 
gs = gridspec.GridSpec(5, miniPlotCount) 
ax = fig.add_subplot(gs[0:4,:], projection='3d') 

miniAxes = [] 
for i in range(miniPlotCount): 
    miniAxes.append(fig.add_subplot(gs[4,i])) 

ax.plot_surface(X,Y,Z1, cmap=cm.jet, linewidth=0.2, cstride=2, rstride=2, facecolors=faceColours, vmin=0, vmax=1) 


#This decides where we draw the rectangle to be inspecting. 
rect = ((25,45),(65,70)) 

boxXs, boxYs, boxZs, middleOfBox = boxOnSurface(rect, X,Y,Z1) 
ax.plot(boxXs, boxYs, boxZs) 

xb, yb, zb = middleOfBox 

xPoint, yPoint, _ = proj3d.proj_transform(xb, yb, zb, ax.get_proj()) 


labels = [] 
grids = [] 
for i in range(miniPlotCount): 
    bbox = miniAxes[i].get_window_extent() 
    xytext = ((bbox.min[0] + bbox.max[0])/2, (bbox.min[1] + bbox.max[1])/2) 
    labels.append(ax.annotate("", xy=(xPoint,yPoint), arrowprops = {"arrowstyle":'->', "connectionstyle":'arc3,rad=0'}, textcoords="figure pixels", xytext=xytext)) 

# miniAxes[i].contourf(X[rect[0][0]:rect[1][0],rect[0][1]:rect[1][1]], Y[rect[0][0]:rect[1][0],rect[0][1]:rect[1][1]], Z1[rect[0][0]:rect[1][0],rect[0][1]:rect[1][1]])#, vmin=Z1.min(), vmax=Z1.max()) 
    miniAxes[i].contourf(X[rect[0][0]:rect[1][0],rect[0][1]:rect[1][1]], Y[rect[0][0]:rect[1][0],rect[0][1]:rect[1][1]], faceValues[rect[0][0]:rect[1][0],rect[0][1]:rect[1][1]], vmin=faceValues.min(), vmax=faceValues.max()) 

# miniAxes[i].set_agg_filter(gaussFilter) 
    gaussFilter = GaussianFilter(i) 
    miniAxes[i].grid(linestyle="-", linewidth=2, agg_filter=gaussFilter) 






def update_position(e): 
    xPoint, yPoint, _ = proj3d.proj_transform(xb, yb, zb, ax.get_proj()) 
    for label in labels: 
     label.xy = xPoint, yPoint 
     label.update_positions(fig.canvas.renderer) 
    fig.canvas.draw() 

fig.canvas.mpl_connect('motion_notify_event', update_position) 




plt.show() 

它創建這樣的:

enter image description here

那已經模糊了網格線。 (我不知道爲什麼它沒有模糊其中兩個)看起來,您可以通過在agg_filter= kwarg中添加您在matplotlib中放置的任何對象的agg_filter。如果您編輯了GaussianFilter課程,您可以使它能夠接收所有不確定性數據,然後使用它將blur/opactiy/whatever應用於圖像的各個部分。