7

在 matplotlib 主页中,有一个指向 Nicolas Rougier 的教程的链接。在题为“Devil is in the details”的教程部分中,脚本:

http://www.loria.fr/~rougier/teaching/matplotlib/scripts/exercice_10.py

生成显示在网页上的图形。脚本的第 48 行是:

label.set_bbox(dict(facecolor='white', edgecolor='None', alpha=0.65 ))

如果我们将这一行替换为:

label.set_bbox({"facecolor": "white", "edgecolor": "None","alpha":0.65})

然后不考虑 edgecolor 请求。我会认为上面的两个陈述是等价的。我曾就此向本教程的作者 Nicolas Rougier 询问过,他也对此感到惊讶。这是 Matplotlib 的错误吗?

4

2 回答 2

4

您可以轻松确定两者dicts是否等效:

dict(facecolor='white', edgecolor='None', alpha=0.65 ) == \
    {"facecolor": "white", "edgecolor": "None", "alpha":0.65}

这是True.

但是,如果您将这些文字输入到 Python 解释器中,则生成的字典reprs 将具有不同顺序的值。

{'alpha': 0.65000000000000002, 'facecolor': 'white', 'edgecolor': 'None'}
{'edgecolor': 'None', 'facecolor': 'white', 'alpha': 0.65000000000000002}

这可能因您使用的 Python 版本而异,我相信在较新版本的 Python 中,它会因解释器的运行而异;哈希播种是随机的,以防止构造恶意性能不佳的字典。以上输出来自 Python 2.6.6 (Win32)。

Pythondict是无序的,我们的意思是你不能依赖顺序。但是,在遍历字典时,元素必须以某种顺序出现。此顺序受插入项目的顺序影响,虽然不明显,但它们在这两个字典中以两种不同的顺序插入:dict()构造函数获取关键字字典,然后将其插入到构造的dict,所以实际上第一个元素dict被插入了两次!首先按照您指定它们的顺序,然后按照它们最终在该步骤中构建的字典中的任何顺序。

假设:(matplotlib或您正在使用的 Python 版本)中有一些东西关心字典项的顺序。事实上,由于第二个有它的edgecolor键,所以它可能跳过第一个值,或者可能是其中一个后面的值有一个副作用,导致它被覆盖edgecolor(例如,可能facecolor还设置edgecolor以确保面之间没有间隙)。这可能被合理地称为错误,因为行为可能会根据关键字从字典中出现的顺序而有所不同。

于 2013-04-19T15:33:31.340 回答
0

如果将该行替换为:

label.set_bbox({"facecolor": "white", "alpha":0.65, "edgecolor": "None",})

它工作正常。

我认为这是渲染器中的错误,set_alpha或者可能是渲染器中的错误。

作为一种解决方法,您可以将线宽设置为 0:

label.set_bbox({"facecolor": "white", "edgecolor": "None","alpha":0.65, 'lw':0})

这将确保不会绘制线条,而与颜色/alpha 无关。

代码的工作方式是传递set_bboxadict然后存储在_bbox. 在绘制时, if _bboxis not None(并且没有_bbox_patch_bbox传递给patches.bbox_artistwhich 是一个函数(在文档字符串中标记为调试函数!),它使用 动态dict生成Rectangle对象(不返回!)。set_*矩形中的某个draw地方是错误所在。

于 2013-04-19T15:59:17.277 回答