matplotlib 中的非闭合轮廓?
Non-closed contours in matplotlib?
在 GIS 预处理器中实现(出色的 matplotlib)等高线绘制时,结果略有不理想 [参见附图以获取参考]。
结果不是理想地展示多段线段(带圆圈的橙色区域),而是封闭的多边形环(绿色突出显示的路径)。
我对游戏逻辑的最佳推断;在所附图像中,从左到右,轮廓级别正在降低。关闭的循环表明 matplotlib.pyplot.contours() 正在将所有值合并到所述级别的范围内 - 因此是闭环?
目标是让这些大致垂直的轮廓水平在所述形状的边界处剪掉。考虑到这些轮廓的路径是用 pyplot 的替代方法抓取和绘制的——内置的遮罩和剪裁看起来可能不适用。
也许我在初始轮廓创建时忽略了文档中的一个论点 - 或者其他一些方法来满足所描述的需求?
感谢您提供线索或智慧。
当前输入:
(meshXList、meshYList 和 valueZList 是位于所示多边形内的各向同性网格质心坐标)
X = np.array(self.meshXList).reshape(self.numRows,self.numCols)
Y = np.array(self.meshYList).reshape(self.numRows,self.numCols)
Z = np.array(self.valueZList).reshape(self.numRows,self.numCols)
conIntrv = float(self.conIntNum.text())
minCon,maxCon = float(self.minConLineNum.text()),float(self.maxConLineNum.text())
numCon = int((maxCon-minCon)/conIntrv)
levels = np.linspace(minCon,maxCon,numCon)
contours = plt.contour(X,Y,Z,levels,antialiased=True)
conCollect = contours.collections
rawContourLines = []
for lineIdx, line in enumerate(conCollect):
lineStrings = []
for path in line.get_paths():
if len(path.vertices)>1:
lineStrings.append(path.vertices)
rawContourLines.append(lineStrings)
更新相关解析:
最高敬意@tom10 提供了对我来说本应显而易见的线索。
附图中的灰色区域包含在meshXList、meshYList和valueZList中;虽然在 GIS 程序中没有选择显示。
了解 valueZList 不需要数值(使用 -999.99999999999),而是可以包含 {None} 揭示了一个非常简单的问题解决方案:
emptValue = None
self.valueZList = [emptValue]*len(self.meshXList)
with open(valueFile, "r") as valueInput:
reader = csv.reader(valueInput)
for idx,row in enumerate(reader):
if idx==0: self.valueType = row[1]
if idx>0:
holdingIdx = int(row[0])
holdingVal = float(row[1])
if '888.88' in holdingVal or '777.77' in holdingVal:
self.valueZList[holdingIdx] = emptValue
else:
self.valueZList[holdingIdx]=holdingVal
if holdingVal<minValue: minValue = holdingVal
if holdingVal>maxValue: maxValue = holdingVal
'None Type' 万岁!
一种方法是将边界外的区域设置为 None
。所以要修改 standard example 以给出 "open" 轮廓:
import matplotlib
import numpy as np
import matplotlib.cm as cm
import matplotlib.mlab as mlab
import matplotlib.pyplot as plt
matplotlib.rcParams['xtick.direction'] = 'out'
matplotlib.rcParams['ytick.direction'] = 'out'
delta = 0.025
x = np.arange(-3.0, 3.0, delta)
y = np.arange(-2.0, 2.0, delta)
X, Y = np.meshgrid(x, y)
Z1 = mlab.bivariate_normal(X, Y, 1.0, 1.0, 0.0, 0.0)
Z2 = mlab.bivariate_normal(X, Y, 1.5, 0.5, 1, 1)
# difference of Gaussians
Z = 10.0 * (Z2 - Z1)
Z[X<-1] = None
Z[X>2] = None
plt.figure()
CS = plt.contour(X, Y, Z, levels=np.arange(-.5, 2, .5))
plt.clabel(CS, inline=1, fontsize=10)
plt.title('Simplest default with labels')
plt.show()
或者,更有趣一点(使用,Z[X*X+(Y-1)**2>3.] = None
):
在 GIS 预处理器中实现(出色的 matplotlib)等高线绘制时,结果略有不理想 [参见附图以获取参考]。
结果不是理想地展示多段线段(带圆圈的橙色区域),而是封闭的多边形环(绿色突出显示的路径)。
我对游戏逻辑的最佳推断;在所附图像中,从左到右,轮廓级别正在降低。关闭的循环表明 matplotlib.pyplot.contours() 正在将所有值合并到所述级别的范围内 - 因此是闭环?
目标是让这些大致垂直的轮廓水平在所述形状的边界处剪掉。考虑到这些轮廓的路径是用 pyplot 的替代方法抓取和绘制的——内置的遮罩和剪裁看起来可能不适用。
也许我在初始轮廓创建时忽略了文档中的一个论点 - 或者其他一些方法来满足所描述的需求?
感谢您提供线索或智慧。
当前输入:
(meshXList、meshYList 和 valueZList 是位于所示多边形内的各向同性网格质心坐标)
X = np.array(self.meshXList).reshape(self.numRows,self.numCols)
Y = np.array(self.meshYList).reshape(self.numRows,self.numCols)
Z = np.array(self.valueZList).reshape(self.numRows,self.numCols)
conIntrv = float(self.conIntNum.text())
minCon,maxCon = float(self.minConLineNum.text()),float(self.maxConLineNum.text())
numCon = int((maxCon-minCon)/conIntrv)
levels = np.linspace(minCon,maxCon,numCon)
contours = plt.contour(X,Y,Z,levels,antialiased=True)
conCollect = contours.collections
rawContourLines = []
for lineIdx, line in enumerate(conCollect):
lineStrings = []
for path in line.get_paths():
if len(path.vertices)>1:
lineStrings.append(path.vertices)
rawContourLines.append(lineStrings)
更新相关解析:
最高敬意@tom10 提供了对我来说本应显而易见的线索。 附图中的灰色区域包含在meshXList、meshYList和valueZList中;虽然在 GIS 程序中没有选择显示。
了解 valueZList 不需要数值(使用 -999.99999999999),而是可以包含 {None} 揭示了一个非常简单的问题解决方案:
emptValue = None
self.valueZList = [emptValue]*len(self.meshXList)
with open(valueFile, "r") as valueInput:
reader = csv.reader(valueInput)
for idx,row in enumerate(reader):
if idx==0: self.valueType = row[1]
if idx>0:
holdingIdx = int(row[0])
holdingVal = float(row[1])
if '888.88' in holdingVal or '777.77' in holdingVal:
self.valueZList[holdingIdx] = emptValue
else:
self.valueZList[holdingIdx]=holdingVal
if holdingVal<minValue: minValue = holdingVal
if holdingVal>maxValue: maxValue = holdingVal
'None Type' 万岁!
一种方法是将边界外的区域设置为 None
。所以要修改 standard example 以给出 "open" 轮廓:
import matplotlib
import numpy as np
import matplotlib.cm as cm
import matplotlib.mlab as mlab
import matplotlib.pyplot as plt
matplotlib.rcParams['xtick.direction'] = 'out'
matplotlib.rcParams['ytick.direction'] = 'out'
delta = 0.025
x = np.arange(-3.0, 3.0, delta)
y = np.arange(-2.0, 2.0, delta)
X, Y = np.meshgrid(x, y)
Z1 = mlab.bivariate_normal(X, Y, 1.0, 1.0, 0.0, 0.0)
Z2 = mlab.bivariate_normal(X, Y, 1.5, 0.5, 1, 1)
# difference of Gaussians
Z = 10.0 * (Z2 - Z1)
Z[X<-1] = None
Z[X>2] = None
plt.figure()
CS = plt.contour(X, Y, Z, levels=np.arange(-.5, 2, .5))
plt.clabel(CS, inline=1, fontsize=10)
plt.title('Simplest default with labels')
plt.show()
或者,更有趣一点(使用,Z[X*X+(Y-1)**2>3.] = None
):