Matplotlib图例高度(以像素为单位) [英] Matplotlib Legend Height in pixels

查看:385
本文介绍了Matplotlib图例高度(以像素为单位)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要知道图例的大小(以像素为单位).我似乎只能从任何函数中获取height = 1.

这将返回1.

height = legend.get_frame().get_bbox_to_anchor().height

这将返回[0,0],[1.,1.]

box = legend.get_window_extent().get_points()

这还将返回[0,0],[1.,1.]

box = legend.get_frame().get_bbox().get_points()

所有这些都返回1,即使图例的大小改变了!发生了什么事?

解决方案

这是因为您尚未绘制画布.

在绘制画布之前,matplotlib中根本不存在像素值(或者说,它们存在,与屏幕或其他输出没有关系).

有很多原因,但此刻我将跳过它们.可以说matplotlib尝试保持尽可能通用,并且通常避免在绘制事物之前使用像素值.

作为一个简单的例子:

import matplotlib.pyplot as plt

fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(range(10), label='Test')
legend = ax.legend(loc='upper left')

print 'Height of legend before canvas is drawn:'
print legend.get_window_extent().height

fig.canvas.draw()

print 'Height of legend after canvas is drawn:'
print legend.get_window_extent().height

但是,这仅表示在屏幕上绘制的图例的高度(以像素为单位).如果保存该图形,它将以与在屏幕上绘制的dpi不同的dpi(默认情况下为100)保存,因此像素的大小将有所不同.

有两种解决方法:

  1. 又脏又臭:在输出像素值之前先绘制图形的画布,并确保在保存时明确指定图形的dpi(例如fig.savefig('temp.png', dpi=fig.dpi).

  2. 推荐,但稍微复杂一点:将回调函数连接到draw事件,并且仅在绘制图形时使用像素值.这样一来,您只需绘制一次图形即可使用像素值.

作为后一种方法的快速示例:

import matplotlib.pyplot as plt

def on_draw(event):
    fig = event.canvas.figure
    ax = fig.axes[0] # I'm assuming only one subplot here!!
    legend = ax.legend_ 
    print legend.get_window_extent().height

fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(range(10), label='Test')
legend = ax.legend(loc='upper left')

fig.canvas.mpl_connect('draw_event', on_draw)

fig.savefig('temp.png')

请注意,第一个和第二个示例的图例高度在打印方式上有所不同. (在我的系统上,第二个为31.0,第一个为24.8,但这取决于您的.matplotlibrc文件)

差异是由于保存图形时默认fig.dpi(默认为80 dpi)和默认分辨率(默认为100 dpi)之间的dpi不同.

希望这还是有道理的.

I need to know the size of the legend in pixels. I seem to only be able to get height = 1. from any function... I've tried the following

this returns 1.

height = legend.get_frame().get_bbox_to_anchor().height

this returns [0,0],[1.,1.]

box = legend.get_window_extent().get_points()

this also returns [0,0],[1.,1.]

box = legend.get_frame().get_bbox().get_points()

all of these return 1, even if the size of the legend changes! what's going on?

解决方案

This is because you haven't yet drawn the canvas.

Pixel values simply don't exist in matplotlib (or rather, they exist, have no relation to the screen or other output) until the canvas is drawn.

There are a number of reasons for this, but I'll skip them at the moment. Suffice it to say that matplotlib tries to stay as general as possible, and generally avoids working with pixel values until things are drawn.

As a simple example:

import matplotlib.pyplot as plt

fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(range(10), label='Test')
legend = ax.legend(loc='upper left')

print 'Height of legend before canvas is drawn:'
print legend.get_window_extent().height

fig.canvas.draw()

print 'Height of legend after canvas is drawn:'
print legend.get_window_extent().height

However, this is only going to represent the height of the legend in pixels as it is drawn on the screen! If you save the figure, it will be saved with a different dpi (100, by default) than it is drawn on the screen, so the size of things in pixels will be different.

There are two ways around this:

  1. Quick and dirty: draw the figure's canvas before outputting pixel values and be sure to explicitly specify the dpi of the figure when saving (e.g. fig.savefig('temp.png', dpi=fig.dpi).

  2. Recommended, but slightly more complicated: Connect a callback to the draw event and only work with pixel values when the figure is drawn. This allows you to work with pixel values while only drawing the figure once.

As a quick example of the latter method:

import matplotlib.pyplot as plt

def on_draw(event):
    fig = event.canvas.figure
    ax = fig.axes[0] # I'm assuming only one subplot here!!
    legend = ax.legend_ 
    print legend.get_window_extent().height

fig = plt.figure()
ax = fig.add_subplot(111)
ax.plot(range(10), label='Test')
legend = ax.legend(loc='upper left')

fig.canvas.mpl_connect('draw_event', on_draw)

fig.savefig('temp.png')

Notice the different in what is printed as the height of the legend for the first and second examples. (31.0 for the second vs. 24.8 for the first, on my system, but this will depend on the defaults in your .matplotlibrc file)

The difference is due to the different dpi between the default fig.dpi (80 dpi, by default) and the default resolution when saving a figure (100 dpi, by default).

Hopefully that makes some sense, anyway.

这篇关于Matplotlib图例高度(以像素为单位)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆