[英]How to make a multi-column text annotation in matplotlib?
matplotlib's legend()
method has an ncol
parameter to lay out the content in multiple columns. matplotlib 的legend()
方法有一个ncol
参数,用于在多列中布置内容。
I want to do the same thing in a text annotation.我想在文本注释中做同样的事情。
I can pass multi-line text string (ie, one that contains \\n
s) to annotate()
, but how can I array the content in two columns?我可以将多行文本字符串(即包含\\n
s 的字符串)传递给annotate()
,但是如何将内容排列成两列?
I couln't find an nice way to do this so I wrote a function that gets the jobs done.我找不到一个很好的方法来做到这一点,所以我写了一个函数来完成工作。 Try it out and see if it does what you need.尝试一下,看看它是否满足您的需求。
def place_column_text(ax, text, xy, wrap_n, shift, bbox=False, **kwargs):
""" Creates a text annotation with the text in columns.
The text columns are provided by a list of strings.
A surrounding box can be added via bbox=True parameter.
If so, FancyBboxPatch kwargs can be specified.
The width of the column can be specified by wrap_n,
the shift parameter determines how far apart the columns are.
The axes are specified by the ax parameter.
Requires:
import textwrap
import matplotlib.patches as mpatches
"""
# place the individual text boxes, with a bbox to extract details from later
x,y = xy
n = 0
text_boxes = []
for i in text:
text = textwrap.fill(i, wrap_n)
box = ax.text(x = x + n, y = y, s=text, va='top', ha='left',
bbox=dict(alpha=0, boxstyle='square,pad=0'))
text_boxes.append(box)
n += shift
if bbox == True: # draw surrounding box
# extract box data
plt.draw() # so we can extract real bbox data
# first let's calulate the height of the largest bbox
heights=[]
for box in text_boxes:
heights.append(box.get_bbox_patch().get_extents().transformed(ax.transData.inverted()).bounds[3])
max_height=max(heights)
# then calculate the furthest x value of the last bbox
end_x = text_boxes[-1].get_window_extent().transformed(ax.transData.inverted()).xmax
# draw final
width = end_x - x
fancypatch_y = y - max_height
rect = mpatches.FancyBboxPatch(xy=(x,fancypatch_y), width=width, height=max_height, **kwargs)
ax.add_patch(rect)
Here is it in use:这是它的使用:
import matplotlib.patches as mpatches
import textwrap
fig, ax = plt.subplots(2,2,sharex=True, sharey=True,figsize=(16,12))
fig.subplots_adjust(hspace=0.05, wspace=0.05)
ax1, ax2, ax3, ax4 = ax.flatten()
for a in ax.flatten():
a.plot(range(0,20),range(0,20), alpha=0)
# the text to be split into columns and annotated
col_text = ['Colum 1 text is this sentence here.',
'The text for column two is going to be longer',
'Column 3 is the third column.',
'And last but not least we have column 4. In fact this text is the longest.']
# use the function to place the text
place_column_text(ax=ax1,text=col_text, xy=(1,10), wrap_n=10, shift=4.2)
place_column_text(ax=ax2,text=col_text, xy=(0,19), wrap_n=17, bbox=True, shift=5, ec='red', fc='w', boxstyle='square')
place_column_text(ax=ax3,text=col_text, xy=(2,18), wrap_n=6, bbox=True, shift=2.7, ec='blue', fc = 'blue' , alpha=0.3, boxstyle='round,pad=1')
place_column_text(ax=ax4,text=col_text, xy=(3,12), wrap_n=10, bbox=True, shift=3, ec='red', fc='w', boxstyle='circle, pad=3')
plt.show()
Result:结果:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.