matplotlib:获取文本边界框,独立于后端

Str*_*tch 9 python matplotlib

我想在matplotlib图中的某些文本周围获取边界框(尺寸).这里的帖子帮助我意识到我可以使用该方法text.get_window_extent(renderer)获取边界框,但我必须提供正确的渲染器.有些后端没有这个方法figure.canvas.get_renderer(),所以我试图matplotlib.backend_bases.RendererBase()获得渲染器并且它没有产生令人满意的结果.这是一个简单的例子

import matplotlib as mpl
import matplotlib.pyplot as plt
from matplotlib.patches import Rectangle

fig = plt.figure()
ax = plt.subplot()
txt = fig.text(0.15,0.5,'afdjsklhvvhwd', fontsize = 36)
renderer1 = fig.canvas.get_renderer()
renderer2 = mpl.backend_bases.RendererBase()
bbox1 = txt.get_window_extent(renderer1)
bbox2 = txt.get_window_extent(renderer2)
rect1 = Rectangle([bbox1.x0, bbox1.y0], bbox1.width, bbox1.height, \
    color = [0,0,0], fill = False)
rect2 = Rectangle([bbox2.x0, bbox2.y0], bbox2.width, bbox2.height, \
    color = [1,0,0], fill = False)
fig.patches.append(rect1)
fig.patches.append(rect2)
plt.draw()
Run Code Online (Sandbox Code Playgroud)

这会产生以下情节:

图片

显然红色框太小了.我认为保罗的答案在这里找到了同样的问题.黑匣子看起来很棒,但我不能使用MacOSX后端,或任何其他没有这种方法的后端figure.canvas.get_renderer().

如果它很重要,我使用的是Mac OS X 10.8.5,Matplotlib 1.3.0和Python 2.7.5

Str*_*tch 7

这是我的解决方案/黑客.@tcaswell建议我看一下matplotlib如何使用紧密的边界框来处理保存数字.我在Github上找到 backend_bases.py 的代码,它将图形保存到临时文件对象,只是为了从缓存中获取渲染器.我将这个技巧变成了一个小函数,get_renderer()如果它存在于后端,则使用内置方法,否则使用save方法.

def find_renderer(fig):

    if hasattr(fig.canvas, "get_renderer"):
        #Some backends, such as TkAgg, have the get_renderer method, which 
        #makes this easy.
        renderer = fig.canvas.get_renderer()
    else:
        #Other backends do not have the get_renderer method, so we have a work 
        #around to find the renderer.  Print the figure to a temporary file 
        #object, and then grab the renderer that was used.
        #(I stole this trick from the matplotlib backend_bases.py 
        #print_figure() method.)
        import io
        fig.canvas.print_pdf(io.BytesIO())
        renderer = fig._cachedRenderer
    return(renderer)
Run Code Online (Sandbox Code Playgroud)

以下是使用find_renderer()我原始示例中稍微修改过的代码版本的结果.使用具有该get_renderer()方法的TkAgg后端,我得到:

TkAgg

使用没有get_renderer()方法的MacOSX后端,我得到:

MacOSX的

显然,使用MacOSX后端的边界框并不完美,但它比我原来问题中的红框要好得多.

  • 它因错误“AttributeError: 'FigureCanvasMac' object has no attribute 'print_pdf' on my MAC而失败。 (2认同)