我遇到了 matplotlib 用来表示刻度标签的 Text 对象的问题。
出于测试原因,我需要检查在图中创建的刻度标签的值。如果标签是字符串或正数,则没有问题:返回 unicode 字符串,我对其进行测试(或根据情况将其转换为数字),一切都很好。
但是,如果标签是负数,我得到的是一个损坏的 unicode 字符串,原因我无法理解。
让我们看这个示例代码:
import pylab as plt
fig, ax = plt.subplots(1)
ax.plot([-1, 0, 1, 2], range(4))
labels = ax.get_xticklabels()
现在,如果我询问第二个标签(的0
)的文本内容,我会得到一个普通的 unicode 字符串:
labels[1].get_text()
# u'0.0'
但是第一个(the -1
)的unicode是一件奇怪的事情
labels[1].get_text()
# u'\u22121'
这在终端中正确打印,但在这种情况下,我需要用一个数值来处理它,并且每次转换都失败,无论是int
和float
。
我尝试将其转换为 UTF-8 字符串
text = labels[1].get_text()
text.encode('utf8')
# '\xe2\x88\x921'
但它再次被正确打印并在转换时引发错误。我也查看了unicodedata
模块,但看起来它只能转换单个字符,所以在这种情况下没用。我也尝试过使用unicodedata.normalize
任何可能的格式来规范化字符串,但同样没有成功。
我搬到了 pipy 模块unidecode
(如Python and character normalization中所建议的那样),再次没有任何成功
from unidecode import unidecode
unidecode(text)
# '[?]1'
我还尝试使用Matplotlib 中的非 ASCII 字符中的解决方案来避免字体问题,但结果相同(我不确定它是否应该有事可做,因为这是一个可视化问题......)。问题Matplotlib 中的Accented characters也有类似的问题,因为它关注的是可视化而不是值本身
我开始感到有点失落......我知道python 2.7有一些unicode“困难”,但通常我可以以某种方式避免它们。
我知道问题是减号,因为我可以通过粗暴替换罪魁祸首来避免问题:
text.replace(u'\u2212', '-')
# u'-1'
但这不仅仅是一个解决方案,而且我几乎可以肯定它在不同的系统中不稳定,所以我想要更接近解决方案的东西。
我正在与
- 蟒蛇2.7.3
- matplotlib 1.2.0
- pylab 1.7.0
- IPython 0.13.1
在 Kubuntu 12.10 上。
非常感谢您的帮助!
编辑:
更正了情节的顺序,因为我把 x 和 y 颠倒了,对不起
编辑2:
此链接中提供了类似的信息:http: //www.coniferproductions.com/2012/12/17/unicode-character-dump-in-python/
最后,它显示了在某些书中使用的减号如何在审美上更令人愉悦,但 Python 解释器不将其识别为有效字符。
编辑3:
谜底解开了。matplotlib 返回的字符是“减号”,即减号的正确印刷符号。键盘创建的实际上是“HYPHEN-MINUS”,这是常用的,但在印刷上不正确。请参阅维基百科上的解释http://en.wikipedia.org/wiki/Hyphen-minus。
因此,我使用的简单替换实际上是正确的实际操作,但“道德上”是 python(2.7 和 3.x 类似)中的一个错误,它无法识别减号的正确符号。
请参阅http://bugs.python.org/issue6632中的错误跟踪
编辑4:
要禁用此行为,matplotlib 上有一个简单的解决方案,只需在 .matplotlibrc 中或以编程方式修改 rcparams。
import matplotlib as mpl
mpl.rcParams['axes.unicode_minus']=False