绘图中文本框的智能自动定位
Smart automatic positioning of text box in plot
我正在按照 Joe Kington in this answer 给出的方法使用 matplotlib.offsetbox.AnchoredText()
模块将文本框放置在图的一角。
如果我知道要将文本框放置在何处,这将非常有效,但是如果我希望文本框自行定位,以便它 与绘制在同一位置的内容的最小可能部分重叠怎么办?图?
这需要尽可能普遍地工作,所以假设我事先不知道绘制的内容是什么以及它在图中的位置。
我查看了 documentation,但似乎没有可用的 smart
选项。位置代码是:
'upper right' : 1,
'upper left' : 2,
'lower left' : 3,
'lower right' : 4,
'right' : 5,
'center left' : 6,
'center right' : 7,
'lower center' : 8,
'upper center' : 9,
'center' : 10,
例如,在这种情况下(下面的 MWE):
更好的位置是左上角(或左下角),但由于我通过loc=1
手动固定了位置,文本框与绘制的内容重叠。
有什么方法可以检测图中哪里有更多可用的空 space 并将框放在那里?
MWE:
import matplotlib.pyplot as plt
import matplotlib.offsetbox as offsetbox
# Define some names and variables to go in the text box.
xn, yn, cod = 'r', 'p', 'abc'
prec = 5
ccl = [546.35642, 6785.35416]
ect = [12.5235, 13.643241]
fig = plt.figure()
ax = fig.add_subplot(111)
ax.axis([0, 5, 0, 1])
import random
pointx = [3. + random.random() for i in xrange(1000)]
pointy = [random.random() for i in xrange(1000)]
plt.scatter(pointx , pointy)
# Generate text to write.
text1 = "${}_{{t}} = {:.{p}f} \pm {:.{p}f}\; {c}$".format(xn, ccl[0],
ect[0], c=cod, p=prec)
text2 = "${}_{{t}} = {:.{p}f} \pm {:.{p}f}\; {c}$".format(yn, ccl[1],
ect[1], c=cod, p=prec)
text = text1 + '\n' + text2
ob = offsetbox.AnchoredText(text, loc=1)
ax.add_artist(ob)
plt.show()
3 年多后,解决方案如下:代替 offsetbox
,只需使用 plt.legend() 并利用它默认将文本框定位在 "best" 位置的能力.
import matplotlib.pyplot as plt
# Define some names and variables to go in the text box.
xn, yn, cod = 'r', 'p', 'abc'
prec = 5
ccl = [546.35642, 6785.35416]
ect = [12.5235, 13.643241]
fig = plt.figure()
ax = fig.add_subplot(111)
ax.axis([0, 5, 0, 1])
import random
pointx = [3. + random.random() for i in xrange(1000)]
pointy = [random.random() for i in xrange(1000)]
plt.scatter(pointx , pointy)
# Generate text to write.
text1 = "${}_{{t}} = {:.{p}f} \pm {:.{p}f}\; {c}$".format(xn, ccl[0],
ect[0], c=cod, p=prec)
text2 = "${}_{{t}} = {:.{p}f} \pm {:.{p}f}\; {c}$".format(yn, ccl[1],
ect[1], c=cod, p=prec)
text = text1 + '\n' + text2
# Create an empty plot with the required text.
plt.plot([], label=text)
# Remove the handle from the legend box.
plt.legend(handlelength=0)
plt.show()
我正在按照 Joe Kington in this answer 给出的方法使用 matplotlib.offsetbox.AnchoredText()
模块将文本框放置在图的一角。
如果我知道要将文本框放置在何处,这将非常有效,但是如果我希望文本框自行定位,以便它 与绘制在同一位置的内容的最小可能部分重叠怎么办?图?
这需要尽可能普遍地工作,所以假设我事先不知道绘制的内容是什么以及它在图中的位置。
我查看了 documentation,但似乎没有可用的 smart
选项。位置代码是:
'upper right' : 1,
'upper left' : 2,
'lower left' : 3,
'lower right' : 4,
'right' : 5,
'center left' : 6,
'center right' : 7,
'lower center' : 8,
'upper center' : 9,
'center' : 10,
例如,在这种情况下(下面的 MWE):
更好的位置是左上角(或左下角),但由于我通过loc=1
手动固定了位置,文本框与绘制的内容重叠。
有什么方法可以检测图中哪里有更多可用的空 space 并将框放在那里?
MWE:
import matplotlib.pyplot as plt
import matplotlib.offsetbox as offsetbox
# Define some names and variables to go in the text box.
xn, yn, cod = 'r', 'p', 'abc'
prec = 5
ccl = [546.35642, 6785.35416]
ect = [12.5235, 13.643241]
fig = plt.figure()
ax = fig.add_subplot(111)
ax.axis([0, 5, 0, 1])
import random
pointx = [3. + random.random() for i in xrange(1000)]
pointy = [random.random() for i in xrange(1000)]
plt.scatter(pointx , pointy)
# Generate text to write.
text1 = "${}_{{t}} = {:.{p}f} \pm {:.{p}f}\; {c}$".format(xn, ccl[0],
ect[0], c=cod, p=prec)
text2 = "${}_{{t}} = {:.{p}f} \pm {:.{p}f}\; {c}$".format(yn, ccl[1],
ect[1], c=cod, p=prec)
text = text1 + '\n' + text2
ob = offsetbox.AnchoredText(text, loc=1)
ax.add_artist(ob)
plt.show()
3 年多后,解决方案如下:代替 offsetbox
,只需使用 plt.legend() 并利用它默认将文本框定位在 "best" 位置的能力.
import matplotlib.pyplot as plt
# Define some names and variables to go in the text box.
xn, yn, cod = 'r', 'p', 'abc'
prec = 5
ccl = [546.35642, 6785.35416]
ect = [12.5235, 13.643241]
fig = plt.figure()
ax = fig.add_subplot(111)
ax.axis([0, 5, 0, 1])
import random
pointx = [3. + random.random() for i in xrange(1000)]
pointy = [random.random() for i in xrange(1000)]
plt.scatter(pointx , pointy)
# Generate text to write.
text1 = "${}_{{t}} = {:.{p}f} \pm {:.{p}f}\; {c}$".format(xn, ccl[0],
ect[0], c=cod, p=prec)
text2 = "${}_{{t}} = {:.{p}f} \pm {:.{p}f}\; {c}$".format(yn, ccl[1],
ect[1], c=cod, p=prec)
text = text1 + '\n' + text2
# Create an empty plot with the required text.
plt.plot([], label=text)
# Remove the handle from the legend box.
plt.legend(handlelength=0)
plt.show()