渲染非均匀网格并在等高线图中标记最大值的位置
Render non-uniform grid and mark maximum value's location in contour plot
matplotlib
中的等高线图有两个问题:
- 如何将任意网格渲染为常规网格?
我希望刻度在两个轴上的位置均匀分布,同时仍然反映我的节点的位置。
- 如何使用彩色标记突出显示数据最高值的位置?
这是我的代码:
import numpy as np
import pylab as pl
def plot_s(data, xlist, ylist):
pl.subplot(111)
x = np.array(xlist)
y = np.array(ylist)
X, Y = np.meshgrid(x, y)
CS = pl.contour(X, Y, data, colors='k')
pl.clabel(CS, inline = 1, fontsize=10)
pl.xlabel('x list')
pl.ylabel('y list')
pl.xticks(xlist)
pl.yticks(ylist)
pl.title('Contour plot')
pl.show()
def main():
data = np.array([[ 0.56555019, 0.57933922, 0.58266252, 0.58067285, 0.57660236, 0.57185625, 0.56711252, 0.55557035, 0.55027705, 0.54480605],
[ 0.55486559, 0.57349717, 0.57940478, 0.57843897, 0.57463271, 0.56963449, 0.5643922 , 0.55095598, 0.54452534, 0.53762606],
[ 0.53529358, 0.56254991, 0.57328105, 0.57409218, 0.57066168, 0.5654082 , 0.55956853, 0.5432474 , 0.53501127, 0.52601203],
[ 0.50110483, 0.54004071, 0.55800178, 0.56173719, 0.55894846, 0.55328279, 0.54642887, 0.52598388, 0.51533094, 0.50354147]])
xlist = [10., 20., 30., 40., 50., 60., 70., 100., 120., 150.]
ylist = [50, 70, 90, 100]
plot_s(data, xlist, ylist)
if __name__ == '__main__':
main()
- 如何将任意网格渲染为常规网格?
一个建议是通过首先在最小和最大 x 和 y 之间创建均匀间隔值的数组来创建规则网格。此外,您可以使用自定义刻度来反映您的 data-points 不等距的事实。请参阅代码中关于我如何实现它的评论。
- 如何使用彩色标记突出显示数据最高值的位置?
要检索最大值,您可以使用 np.max()
,然后使用 np.where
找到该值在 data-array 中的位置。只需在该位置绘制一个标记。
或者,使用 plt.contour
您可以创建一个等高线,其水平足够接近最大值的位置,在其周围创建一个环,甚至在其上创建一个点:
epsillon = 0.0001
levels = np.arange(max_value - epsillon, max_value + epsillon)
CS2 = plt.contour(X,Y,data, levels,
origin='lower',
linewidths=2,
extent=(-3,3,-2,2))
请注意,使用第一种方法时,点将位于现有网格节点的顶部,而 plt.contour
会对您的数据进行插值,并且根据所使用的插值算法,它可能会导致一些不同的位置。然而在这里它似乎同意。
代码:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib
def plot_s(data, x, y, xlist, ylist):
ax = plt.gca()
########### create your uniform meshgrid..... ############
X, Y = np.meshgrid(x, y)
CS = ax.contour(X, Y, data, colors='k')
###### ... and let ticks indicate that your new space is not linear
# assign tick positions according to the regular array
ax.set_yticks(y)
# Assign the label to reflect your original nodes position
ax.set_yticklabels(ylist)
# and same for x
ax.set_xticks(x)
ax.set_xticklabels(xlist)
#############################################################
########### GET MAXIMUM AND MARK IT WITH A POINT ########
# get maximum value in your data
max_value = np.max(data)
# get position index of this calue in your data array
local_max_index = np.where(data==max_value)
## retrieve position of your
max_x = X[local_max_index[0], local_max_index[1]]
max_y = Y[local_max_index[0], local_max_index[1]]
# plot one marker on this position
plt.plot(max_x, max_y, color="red", marker = "o", zorder = 10,
markersize=15, clip_on=False)
##############################################################
plt.title('Contour plot')
plt.show()
def main():
# Your data: 4 x 10 array
data = np.array([[ 0.56555019, 0.57933922, 0.58266252, 0.58067285, 0.57660236,
0.57185625, 0.56711252, 0.55557035, 0.55027705, 0.54480605],
[ 0.55486559, 0.57349717, 0.57940478, 0.57843897, 0.57463271,
0.56963449, 0.5643922 , 0.55095598, 0.54452534, 0.53762606],
[ 0.53529358, 0.56254991, 0.57328105, 0.57409218, 0.57066168,
0.5654082 , 0.55956853, 0.5432474 , 0.53501127, 0.52601203],
[ 0.50110483, 0.54004071, 0.55800178, 0.56173719, 0.55894846,
0.55328279, 0.54642887, 0.52598388, 0.51533094, 0.50354147]])
# create a list values with regular interval for the mesh grid
x = np.array([10 + i * (150.-10.)/9 for i in range(10)])
y = np.array([50 + i * (100.-50.)/4 for i in range(4)])
# create arrays with values to be displayed as ticks
xlist = np.array([10., 20., 30., 40., 50., 60., 70., 100., 120., 150.])
ylist = np.array([50, 70, 90, 100])
plot_s(data, x, y, xlist, ylist)
if __name__ == '__main__':
main()
瞧:
这里用背景网格显示 deformation/mapping:
下面与 snake_charmer 提出的内容基本相同,但稍微更紧凑一些。但是,我不确定我是否正确理解了你的问题。如果 xlist
和 ylist
中的点间距不是太不规则,更优雅的解决方案可能是保留不规则网格,但使用 ax.grid()
突出显示数据点的位置。不过,这取决于您想在图中显示的内容。
import numpy as np
from matplotlib import pyplot as plt
def plot_s(data, xlist, ylist):
fig, ax = plt.subplots()
x = np.arange(len(xlist))
y = np.arange(len(ylist))
X, Y = np.meshgrid(x, y)
CS = ax.contour(X, Y, data, colors='k')
ax.clabel(CS, inline = 1, fontsize=10)
ax.set_xlabel('x list')
ax.set_ylabel('y list')
ax.set_xticks(x)
ax.set_yticks(y)
ax.set_xticklabels(xlist)
ax.set_yticklabels(ylist)
jmax, imax = np.unravel_index(np.argmax(data), data.shape)
ax.plot(imax, jmax, 'ro')
ax.set_title('Contour plot')
plt.show()
def main():
data = np.array([[ 0.56555019, 0.57933922, 0.58266252, 0.58067285,
0.57660236, 0.57185625, 0.56711252, 0.55557035,
0.55027705, 0.54480605],
[ 0.55486559, 0.57349717, 0.57940478, 0.57843897,
0.57463271, 0.56963449, 0.5643922 , 0.55095598,
0.54452534, 0.53762606],
[ 0.53529358, 0.56254991, 0.57328105, 0.57409218,
0.57066168, 0.5654082 , 0.55956853, 0.5432474 ,
0.53501127, 0.52601203],
[ 0.50110483, 0.54004071, 0.55800178, 0.56173719,
0.55894846, 0.55328279, 0.54642887, 0.52598388,
0.51533094, 0.50354147]])
xlist = [10., 20., 30., 40., 50., 60., 70., 100., 120., 150.]
ylist = [50, 70, 90, 100]
plot_s(data, xlist, ylist)
if __name__ == '__main__':
main()
matplotlib
中的等高线图有两个问题:
- 如何将任意网格渲染为常规网格?
我希望刻度在两个轴上的位置均匀分布,同时仍然反映我的节点的位置。
- 如何使用彩色标记突出显示数据最高值的位置?
这是我的代码:
import numpy as np
import pylab as pl
def plot_s(data, xlist, ylist):
pl.subplot(111)
x = np.array(xlist)
y = np.array(ylist)
X, Y = np.meshgrid(x, y)
CS = pl.contour(X, Y, data, colors='k')
pl.clabel(CS, inline = 1, fontsize=10)
pl.xlabel('x list')
pl.ylabel('y list')
pl.xticks(xlist)
pl.yticks(ylist)
pl.title('Contour plot')
pl.show()
def main():
data = np.array([[ 0.56555019, 0.57933922, 0.58266252, 0.58067285, 0.57660236, 0.57185625, 0.56711252, 0.55557035, 0.55027705, 0.54480605],
[ 0.55486559, 0.57349717, 0.57940478, 0.57843897, 0.57463271, 0.56963449, 0.5643922 , 0.55095598, 0.54452534, 0.53762606],
[ 0.53529358, 0.56254991, 0.57328105, 0.57409218, 0.57066168, 0.5654082 , 0.55956853, 0.5432474 , 0.53501127, 0.52601203],
[ 0.50110483, 0.54004071, 0.55800178, 0.56173719, 0.55894846, 0.55328279, 0.54642887, 0.52598388, 0.51533094, 0.50354147]])
xlist = [10., 20., 30., 40., 50., 60., 70., 100., 120., 150.]
ylist = [50, 70, 90, 100]
plot_s(data, xlist, ylist)
if __name__ == '__main__':
main()
- 如何将任意网格渲染为常规网格?
一个建议是通过首先在最小和最大 x 和 y 之间创建均匀间隔值的数组来创建规则网格。此外,您可以使用自定义刻度来反映您的 data-points 不等距的事实。请参阅代码中关于我如何实现它的评论。
- 如何使用彩色标记突出显示数据最高值的位置?
要检索最大值,您可以使用 np.max()
,然后使用 np.where
找到该值在 data-array 中的位置。只需在该位置绘制一个标记。
或者,使用 plt.contour
您可以创建一个等高线,其水平足够接近最大值的位置,在其周围创建一个环,甚至在其上创建一个点:
epsillon = 0.0001
levels = np.arange(max_value - epsillon, max_value + epsillon)
CS2 = plt.contour(X,Y,data, levels,
origin='lower',
linewidths=2,
extent=(-3,3,-2,2))
请注意,使用第一种方法时,点将位于现有网格节点的顶部,而 plt.contour
会对您的数据进行插值,并且根据所使用的插值算法,它可能会导致一些不同的位置。然而在这里它似乎同意。
代码:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib
def plot_s(data, x, y, xlist, ylist):
ax = plt.gca()
########### create your uniform meshgrid..... ############
X, Y = np.meshgrid(x, y)
CS = ax.contour(X, Y, data, colors='k')
###### ... and let ticks indicate that your new space is not linear
# assign tick positions according to the regular array
ax.set_yticks(y)
# Assign the label to reflect your original nodes position
ax.set_yticklabels(ylist)
# and same for x
ax.set_xticks(x)
ax.set_xticklabels(xlist)
#############################################################
########### GET MAXIMUM AND MARK IT WITH A POINT ########
# get maximum value in your data
max_value = np.max(data)
# get position index of this calue in your data array
local_max_index = np.where(data==max_value)
## retrieve position of your
max_x = X[local_max_index[0], local_max_index[1]]
max_y = Y[local_max_index[0], local_max_index[1]]
# plot one marker on this position
plt.plot(max_x, max_y, color="red", marker = "o", zorder = 10,
markersize=15, clip_on=False)
##############################################################
plt.title('Contour plot')
plt.show()
def main():
# Your data: 4 x 10 array
data = np.array([[ 0.56555019, 0.57933922, 0.58266252, 0.58067285, 0.57660236,
0.57185625, 0.56711252, 0.55557035, 0.55027705, 0.54480605],
[ 0.55486559, 0.57349717, 0.57940478, 0.57843897, 0.57463271,
0.56963449, 0.5643922 , 0.55095598, 0.54452534, 0.53762606],
[ 0.53529358, 0.56254991, 0.57328105, 0.57409218, 0.57066168,
0.5654082 , 0.55956853, 0.5432474 , 0.53501127, 0.52601203],
[ 0.50110483, 0.54004071, 0.55800178, 0.56173719, 0.55894846,
0.55328279, 0.54642887, 0.52598388, 0.51533094, 0.50354147]])
# create a list values with regular interval for the mesh grid
x = np.array([10 + i * (150.-10.)/9 for i in range(10)])
y = np.array([50 + i * (100.-50.)/4 for i in range(4)])
# create arrays with values to be displayed as ticks
xlist = np.array([10., 20., 30., 40., 50., 60., 70., 100., 120., 150.])
ylist = np.array([50, 70, 90, 100])
plot_s(data, x, y, xlist, ylist)
if __name__ == '__main__':
main()
瞧:
这里用背景网格显示 deformation/mapping:
下面与 snake_charmer 提出的内容基本相同,但稍微更紧凑一些。但是,我不确定我是否正确理解了你的问题。如果 xlist
和 ylist
中的点间距不是太不规则,更优雅的解决方案可能是保留不规则网格,但使用 ax.grid()
突出显示数据点的位置。不过,这取决于您想在图中显示的内容。
import numpy as np
from matplotlib import pyplot as plt
def plot_s(data, xlist, ylist):
fig, ax = plt.subplots()
x = np.arange(len(xlist))
y = np.arange(len(ylist))
X, Y = np.meshgrid(x, y)
CS = ax.contour(X, Y, data, colors='k')
ax.clabel(CS, inline = 1, fontsize=10)
ax.set_xlabel('x list')
ax.set_ylabel('y list')
ax.set_xticks(x)
ax.set_yticks(y)
ax.set_xticklabels(xlist)
ax.set_yticklabels(ylist)
jmax, imax = np.unravel_index(np.argmax(data), data.shape)
ax.plot(imax, jmax, 'ro')
ax.set_title('Contour plot')
plt.show()
def main():
data = np.array([[ 0.56555019, 0.57933922, 0.58266252, 0.58067285,
0.57660236, 0.57185625, 0.56711252, 0.55557035,
0.55027705, 0.54480605],
[ 0.55486559, 0.57349717, 0.57940478, 0.57843897,
0.57463271, 0.56963449, 0.5643922 , 0.55095598,
0.54452534, 0.53762606],
[ 0.53529358, 0.56254991, 0.57328105, 0.57409218,
0.57066168, 0.5654082 , 0.55956853, 0.5432474 ,
0.53501127, 0.52601203],
[ 0.50110483, 0.54004071, 0.55800178, 0.56173719,
0.55894846, 0.55328279, 0.54642887, 0.52598388,
0.51533094, 0.50354147]])
xlist = [10., 20., 30., 40., 50., 60., 70., 100., 120., 150.]
ylist = [50, 70, 90, 100]
plot_s(data, xlist, ylist)
if __name__ == '__main__':
main()