2016-03-19 18 views
4

Ben Matplotlib examplePython: Matplotlib ile "kısmi" bir yüzey arsivini çizmenin bir yolu var mı?

o X-Y düzlemi üzerinde tam bir meshgrid olmadığını Not ama üst görünümden bir köşeyi eksik aşağıdaki gibi bir "kısmi" yüzey arsa çizmek istedik. Aşağıdaki, denedim ama çalışmadı koddur.

import numpy as np 
from matplotlib import pyplot 
from mpl_toolkits.mplot3d import Axes3D 

X = np.array([[0,1], 
       [0,1,2], 
       [0,1,2,3], 
      ]) 
Y = np.array([[0,0], 
       [1,1,1], 
       [2,2,2,2], 
      ]) 
Z = np.array([[0.5, 0.6], 
       [0.7, 0.8, 0.9], 
       [1.0, 1.1, 1.2, 1.3], 
      ]) 
fig = pyplot.figure() 
ax = fig.add_subplot(111, projection='3d') 
ax.plot_surface(X,Y,Z) 

hata varlık: Herhangi işaretçi mutluluk duyacağız

ValueError: setting an array element with a sequence.

! Teşekkürler!

cevap

4

Bunu yapmak istemediğiniz bölgelerde Z için np.nan değerlerini kullanarak bunu kolayca yapabilirsiniz. Ben atılmış olacağını arsa komutu veya renk ölçeklendirilerek vmin ve vmax anahtar kelimeleri kullanmak zorunda kaldığını burada da

enter image description here

from mpl_toolkits.mplot3d import Axes3D 
from matplotlib import cm 
from matplotlib.ticker import LinearLocator, FormatStrFormatter 
import matplotlib.pyplot as plt 
import numpy as np 

fig = plt.figure() 
ax = fig.gca(projection='3d') 
X = np.arange(-5, 5, 0.25) 
Y = np.arange(-5, 5, 0.25) 
X, Y = np.meshgrid(X, Y) 
R = np.sqrt(X**2 + Y**2) 
Z = np.sin(.5*R) 

Z[X+Y>4.] = np.nan # the diagonal slice 

surf = ax.plot_surface(X, Y, Z, rstride=1, cstride=1, cmap=cm.coolwarm, 
         linewidth=0, antialiased=False, vmin=-1, vmax=1) 
ax.set_zlim(-1.01, 1.01) 

ax.zaxis.set_major_locator(LinearLocator(10)) 
ax.zaxis.set_major_formatter(FormatStrFormatter('%.02f')) 

fig.colorbar(surf, shrink=0.5, aspect=5) 

plt.show() 

Not: Burada this example ait ama kesilmiş değiştirilmiş versiyonu aşağıda gösterildiği gibi, var Nans tarafından.

+0

Temiz çözüm! Bunu denemeye devam ettim, ancak eksik olan değerlerle başa çıkmak için sınırları belirlemem gerektiğini fark etmemiştim. – Crebit

+0

@Crebit: Teşekkürler. Matplotlib'in sınır hesaplamalarında nansları görmezden gelmesi gerektiği anlaşılıyor. Belki şimdi yapmanın bir yolu var, ya da bir hata raporu/özellik isteğine değer olabilir. – tom10

0

Alt diziler aynı uzunluklara sahip olmalıdır. örn .:

X = np.array([[0,1,0,0], 
       [0,1,2,0], 
       [0,1,2,3] 
      ]) 

vb.

+0

Doğru, şu anda benim çözümüm en azından çalışmak için bu noktaları 0'larla doldurmak. Ancak 0'lar yine de grafikte görünecek. Her şeyden sonra 0s "hiçbir şey" ile aynı değildir. – Shawn

+0

Ah görüyorum.Ama sürekli olmayan bir şey çizmek genellikle mümkün olduğunu sanmıyorum. Ve bildiğim kadarıyla, üçgen bir matris "üçgen değil" kısmı için sıfırdan oluşur. – MEVIS3000

+0

oh açıklık için teşekkürler! Sadece neye benzediğini anlatmaya çalışıyordum. Düzenleyeceğim, böylece kafa karıştırıcı olmayacaktır. – Shawn

1

DÜZENLEME: Lütfen tom10'un cevabına bakınız. Onun çözümü, dışlanan kısmın değerlerini np.nans olarak ayarlayarak çalışır.

Matplotlib'in plot_surface'i np.nans'ı koordinat olarak kabul etmiyor gibi görünüyor, bu da işe yaramıyor. Sorunuzu doğru bir şekilde anlarsam, o zaman en azından bir bant bant çözümü sunuyoruz:

MEVIS3000 gibi "kesilen" noktaları sıfırlamak yerine, bunları bu boyuttaki son değere ayarlarsınız. o zaman 2d dizilerinizin hepsi aynı boyuta sahip olacak ve yüzey oradan kesilmiş gibi görünecektir.

Daha net hale getirmek için örneğinize bazı veri noktaları ekledim. Biz yerini böylece biz diziler ayarlarsanız, Şimdi Pic 1: surface with original data

:

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


X = np.array([[0, 1, 2, 3, 4, 5], 
       [0, 1, 2, 3, 4, 5], 
       [0, 1, 2, 3, 4, 5], 
      ]) 
Y = np.array([[0, 0, 0, 0, 0, 0], 
       [1, 1, 1, 1, 1, 1], 
       [2, 2, 2, 2, 2, 2], 
      ]) 
Z = np.array([[0.5, 0.4, 0.35, 0.32, 0.312, 0.3], 
       [0.9, 0.7, 0.60, 0.55, 0.525, 0.5], 
       [1.0, 1.1, 1.20, 1.30, 1.400, 1.5], 
      ]) 


fig = plt.figure() 
ax = fig.add_subplot(111, projection='3d') 
ax.plot_surface(X,Y,Z) 

plt.show() 

çıkan yüzey (baş itibaren) şöyle görünür: Bu (tüm yüzey görünür) başlangıç ​​noktasıdır bu satırdaki önceki değerlerle "eksik" değerleri biz yüzeyinin bir bölümünü dışarıda bırakabilir:

X = np.array([[0, 1, 2, 2, 2, 2], # Notice the sequence 0, 1, 2, 2, 2... 
       [0, 1, 2, 3, 3, 3], # Here starting from 3 
       [0, 1, 2, 3, 4, 4], # Here starting from 4 
      ]) 
Y = np.array([[0, 0, 0, 0, 0, 0], # Here we don't need to do anything 
       [1, 1, 1, 1, 1, 1], 
       [2, 2, 2, 2, 2, 2], 
      ]) 
Z = np.array([[0.5, 0.4, 0.35, 0.35, 0.35, 0.35], # Here like in X: repeats from 0.35 
       [0.9, 0.7, 0.60, 0.55, 0.55, 0.55], 
       [1.0, 1.1, 1.20, 1.30, 1.40, 1.40], 
      ]) 

çıkan grafiği (aynı görünümden tekrar) şöyle görünür: Pic 2: lower right corner cut out

Bu oldukça düzeltici bir çözüm değil, ancak bunu yapmanın bir yolu. Seni bir şekilde "cutoff" 'u otomatikleştirme problemi ile bırakacağım.

İlgili konular