当我提供更多数据点时,matplotlib tricontourf 问题
matplotlib tricontourf ploblem when I give more data point
我在绘制压力图时遇到了问题。
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.tri as mtri
import matplotlib.cm as cm
def plot(x_plot, y_plot, a_plot):
x = np.array(x_plot)
y = np.array(y_plot)
a = np.array(a_plot)
triang = mtri.Triangulation(x, y)
refiner = mtri.UniformTriRefiner(triang)
tri_refi, z_test_refi = refiner.refine_field(a, subdiv=4)
plt.figure(figsize=(18, 9))
plt.gca().set_aspect('equal')
# levels = np.arange(23.4, 23.7, 0.025)
levels = np.linspace(a.min(), a.max(), num=1000)
cmap = cm.get_cmap(name='jet')
plt.tricontourf(tri_refi, z_test_refi, levels=levels, cmap=cmap)
plt.scatter(x, y, c=a, cmap=cmap)
plt.colorbar()
plt.title('stress plot')
plt.show()
首先我只用了8个点就画好了:
x = [2.3384750000000003, 3.671702, 0.3356813, 3.325298666666667, 2.660479, 1.3271675666666667, 1.6680919666666665, 0.6659845666666667]
y = [0.614176, 0.5590579999999999, 0.663329, 0.24002166666666666, 0.26821433333333333, 0.31229233333333334, 0.6367503333333334, 0.3250663333333333]
a = [2.572, 0.8214, 5.689, -0.8214, -2.572, -4.292, 4.292, -5.689]
plot(x, y, a)
然后我尝试给出矩形边界的信息:
x = [2.3384750000000003, 1.983549, 3.018193, 2.013683, 3.671702, 3.978008, 4.018905, 0.3356813, 0.0, 0.0, 1.0070439, 3.325298666666667, 2.979695, 2.660479, 1.3271675666666667, 0.9909098, 1.6680919666666665, 0.6659845666666667]
y = [0.614176, -0.038322, 0.922264, 0.958586, 0.5590579999999999, -0.1229, 0.87781, 0.663329, 1.0, 0.0, 0.989987, 0.24002166666666666, -0.079299, 0.26821433333333333, 0.31229233333333334, -0.014787999999999999, 0.6367503333333334, 0.3250663333333333]
a = [2.572, 2.572, 2.572, 2.572, 0.8214, 0.8214, 0.8214, 5.689, 5.689, 5.689, 5.689, -0.8214, -0.8214, -2.572, -4.292, -4.292, 4.292, -5.689]
plot(x, y, a)
我不知道如何解决它,也不知道为什么会这样。
我想要的数字是:
我画了第二张图中每个点的散点图,都是正确的,但为什么颜色不是轮廓。
非常感谢。
UniformTriRefiner
返回的字段在附加点的情况下不能很好地插值。相反,它引入了新的最小值和最大值,其值最多是原始点的 20 倍。
下图显示了正在发生的事情。
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.tri as mtri
import matplotlib.cm as cm
def plot(x_plot, y_plot, a_plot, ax=None):
if ax == None: ax = plt.gca()
x = np.array(x_plot)
y = np.array(y_plot)
a = np.array(a_plot)
triang = mtri.Triangulation(x, y)
refiner = mtri.UniformTriRefiner(triang)
tri_refi, z_test_refi = refiner.refine_field(a, subdiv=2)
levels = np.linspace(z_test_refi.min(), z_test_refi.max(), num=100)
cmap = cm.get_cmap(name='jet')
tric = ax.tricontourf(tri_refi, z_test_refi, levels=levels, cmap=cmap)
ax.scatter(x, y, c=a, cmap=cmap, vmin= z_test_refi.min(),vmax= z_test_refi.max())
fig.colorbar(tric, ax=ax)
ax.set_title('stress plot')
fig, (ax, ax2) = plt.subplots(nrows=2, sharey=True,sharex=True, subplot_kw={"aspect":"equal"} )
x = [2.3384750000000003, 3.671702, 0.3356813, 3.325298666666667, 2.660479, 1.3271675666666667, 1.6680919666666665, 0.6659845666666667]
y = [0.614176, 0.5590579999999999, 0.663329, 0.24002166666666666, 0.26821433333333333, 0.31229233333333334, 0.6367503333333334, 0.3250663333333333]
a = [2.572, 0.8214, 5.689, -0.8214, -2.572, -4.292, 4.292, -5.689]
plot(x, y, a, ax)
x = [2.3384750000000003, 1.983549, 3.018193, 2.013683, 3.671702, 3.978008, 4.018905, 0.3356813, 0.0, 0.0, 1.0070439, 3.325298666666667, 2.979695, 2.660479, 1.3271675666666667, 0.9909098, 1.6680919666666665, 0.6659845666666667]
y = [0.614176, -0.038322, 0.922264, 0.958586, 0.5590579999999999, -0.1229, 0.87781, 0.663329, 1.0, 0.0, 0.989987, 0.24002166666666666, -0.079299, 0.26821433333333333, 0.31229233333333334, -0.014787999999999999, 0.6367503333333334, 0.3250663333333333]
a = [2.572, 2.572, 2.572, 2.572, 0.8214, 0.8214, 0.8214, 5.689, 5.689, 5.689, 5.689, -0.8214, -0.8214, -2.572, -4.292, -4.292, 4.292, -5.689]
plot(x, y, a, ax2)
plt.show()
可以看出,“插值”字段的值大大超出了原始值。
原因是默认情况下,UniformTriRefiner.refine_field
使用三次插值 (a CubicTriInterpolator
)。文档说明
The interpolation is based on a Clough-Tocher subdivision scheme of the triangulation mesh (to make it clearer, each triangle of the grid will be divided in 3 child-triangles, and on each child triangle the interpolated function is a cubic polynomial of the 2 coordinates). This technique originates from FEM (Finite Element Method) analysis; the element used is a reduced Hsieh-Clough-Tocher (HCT) element. Its shape functions are described in 1. The assembled function is guaranteed to be C1-smooth, i.e. it is continuous and its first derivatives are also continuous (this is easy to show inside the triangles but is also true when crossing the edges).
In the default case (kind ='min_E'), the interpolant minimizes a curvature energy on the functional space generated by the HCT element shape functions - with imposed values but arbitrary derivatives at each node.
虽然这确实是非常技术性的,但我强调了一些重要的部分,即插值是平滑且连续的,具有定义的导数。为了保证这种行为,当数据非常稀疏但幅度波动很大时,超调是不可避免的。
这里的数据根本不适合做三次插值。人们要么尝试获取更密集的数据,要么改用线性插值。
我在绘制压力图时遇到了问题。
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.tri as mtri
import matplotlib.cm as cm
def plot(x_plot, y_plot, a_plot):
x = np.array(x_plot)
y = np.array(y_plot)
a = np.array(a_plot)
triang = mtri.Triangulation(x, y)
refiner = mtri.UniformTriRefiner(triang)
tri_refi, z_test_refi = refiner.refine_field(a, subdiv=4)
plt.figure(figsize=(18, 9))
plt.gca().set_aspect('equal')
# levels = np.arange(23.4, 23.7, 0.025)
levels = np.linspace(a.min(), a.max(), num=1000)
cmap = cm.get_cmap(name='jet')
plt.tricontourf(tri_refi, z_test_refi, levels=levels, cmap=cmap)
plt.scatter(x, y, c=a, cmap=cmap)
plt.colorbar()
plt.title('stress plot')
plt.show()
首先我只用了8个点就画好了:
x = [2.3384750000000003, 3.671702, 0.3356813, 3.325298666666667, 2.660479, 1.3271675666666667, 1.6680919666666665, 0.6659845666666667]
y = [0.614176, 0.5590579999999999, 0.663329, 0.24002166666666666, 0.26821433333333333, 0.31229233333333334, 0.6367503333333334, 0.3250663333333333]
a = [2.572, 0.8214, 5.689, -0.8214, -2.572, -4.292, 4.292, -5.689]
plot(x, y, a)
然后我尝试给出矩形边界的信息:
x = [2.3384750000000003, 1.983549, 3.018193, 2.013683, 3.671702, 3.978008, 4.018905, 0.3356813, 0.0, 0.0, 1.0070439, 3.325298666666667, 2.979695, 2.660479, 1.3271675666666667, 0.9909098, 1.6680919666666665, 0.6659845666666667]
y = [0.614176, -0.038322, 0.922264, 0.958586, 0.5590579999999999, -0.1229, 0.87781, 0.663329, 1.0, 0.0, 0.989987, 0.24002166666666666, -0.079299, 0.26821433333333333, 0.31229233333333334, -0.014787999999999999, 0.6367503333333334, 0.3250663333333333]
a = [2.572, 2.572, 2.572, 2.572, 0.8214, 0.8214, 0.8214, 5.689, 5.689, 5.689, 5.689, -0.8214, -0.8214, -2.572, -4.292, -4.292, 4.292, -5.689]
plot(x, y, a)
我不知道如何解决它,也不知道为什么会这样。 我想要的数字是:
我画了第二张图中每个点的散点图,都是正确的,但为什么颜色不是轮廓。
非常感谢。
UniformTriRefiner
返回的字段在附加点的情况下不能很好地插值。相反,它引入了新的最小值和最大值,其值最多是原始点的 20 倍。
下图显示了正在发生的事情。
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.tri as mtri
import matplotlib.cm as cm
def plot(x_plot, y_plot, a_plot, ax=None):
if ax == None: ax = plt.gca()
x = np.array(x_plot)
y = np.array(y_plot)
a = np.array(a_plot)
triang = mtri.Triangulation(x, y)
refiner = mtri.UniformTriRefiner(triang)
tri_refi, z_test_refi = refiner.refine_field(a, subdiv=2)
levels = np.linspace(z_test_refi.min(), z_test_refi.max(), num=100)
cmap = cm.get_cmap(name='jet')
tric = ax.tricontourf(tri_refi, z_test_refi, levels=levels, cmap=cmap)
ax.scatter(x, y, c=a, cmap=cmap, vmin= z_test_refi.min(),vmax= z_test_refi.max())
fig.colorbar(tric, ax=ax)
ax.set_title('stress plot')
fig, (ax, ax2) = plt.subplots(nrows=2, sharey=True,sharex=True, subplot_kw={"aspect":"equal"} )
x = [2.3384750000000003, 3.671702, 0.3356813, 3.325298666666667, 2.660479, 1.3271675666666667, 1.6680919666666665, 0.6659845666666667]
y = [0.614176, 0.5590579999999999, 0.663329, 0.24002166666666666, 0.26821433333333333, 0.31229233333333334, 0.6367503333333334, 0.3250663333333333]
a = [2.572, 0.8214, 5.689, -0.8214, -2.572, -4.292, 4.292, -5.689]
plot(x, y, a, ax)
x = [2.3384750000000003, 1.983549, 3.018193, 2.013683, 3.671702, 3.978008, 4.018905, 0.3356813, 0.0, 0.0, 1.0070439, 3.325298666666667, 2.979695, 2.660479, 1.3271675666666667, 0.9909098, 1.6680919666666665, 0.6659845666666667]
y = [0.614176, -0.038322, 0.922264, 0.958586, 0.5590579999999999, -0.1229, 0.87781, 0.663329, 1.0, 0.0, 0.989987, 0.24002166666666666, -0.079299, 0.26821433333333333, 0.31229233333333334, -0.014787999999999999, 0.6367503333333334, 0.3250663333333333]
a = [2.572, 2.572, 2.572, 2.572, 0.8214, 0.8214, 0.8214, 5.689, 5.689, 5.689, 5.689, -0.8214, -0.8214, -2.572, -4.292, -4.292, 4.292, -5.689]
plot(x, y, a, ax2)
plt.show()
可以看出,“插值”字段的值大大超出了原始值。
原因是默认情况下,UniformTriRefiner.refine_field
使用三次插值 (a CubicTriInterpolator
)。文档说明
The interpolation is based on a Clough-Tocher subdivision scheme of the triangulation mesh (to make it clearer, each triangle of the grid will be divided in 3 child-triangles, and on each child triangle the interpolated function is a cubic polynomial of the 2 coordinates). This technique originates from FEM (Finite Element Method) analysis; the element used is a reduced Hsieh-Clough-Tocher (HCT) element. Its shape functions are described in 1. The assembled function is guaranteed to be C1-smooth, i.e. it is continuous and its first derivatives are also continuous (this is easy to show inside the triangles but is also true when crossing the edges).
In the default case (kind ='min_E'), the interpolant minimizes a curvature energy on the functional space generated by the HCT element shape functions - with imposed values but arbitrary derivatives at each node.
虽然这确实是非常技术性的,但我强调了一些重要的部分,即插值是平滑且连续的,具有定义的导数。为了保证这种行为,当数据非常稀疏但幅度波动很大时,超调是不可避免的。
这里的数据根本不适合做三次插值。人们要么尝试获取更密集的数据,要么改用线性插值。