unicode 减号的转换(来自 matplotlib ticklabels)
Posted
技术标签:
【中文标题】unicode 减号的转换(来自 matplotlib ticklabels)【英文标题】:Conversion of unicode minus sign ( from matplotlib ticklabels ) 【发布时间】:2013-03-10 09:45:13 【问题描述】: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'
但第一个(-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'
我也尝试使用Non-ASCII characters in Matplotlib 中的解决方案来避免字体问题,但结果相同(我不确定它是否应该做点什么,因为这是一个可视化问题......)。问题Accented characters in Matplotlib 也有类似的问题,因为它关注的是可视化而不是本身的价值
我开始感到有些失落...我知道 python 2.7 有一些 unicode “困难”,但通常我可以通过某种方式避免它们。
我知道问题是减号,因为我可以通过粗暴替换罪魁祸首来避免问题:
text.replace(u'\u2212', '-')
# u'-1'
但这不仅仅是一个解决方案,而且我几乎可以肯定它在不同系统中不稳定,所以我想要更接近解决方案的东西。
我正在合作
python 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中的错误跟踪
EDIT4:
要禁用此行为,matplotlib 上有一个简单的解决方案,只需在 .matplotlibrc 中或以编程方式修改 rcparams。
import matplotlib as mpl
mpl.rcParams['axes.unicode_minus']=False
【问题讨论】:
您上次的编辑解决了我的减号不呈现的问题,谢谢 我建议你把你的EDIT4变成一个答案,这样搜索它的人就可以更容易地找到它! 我只在使用Arial
字体系列在agg
后端保存为pdf
时遇到此问题。 png
结果很好。任何想法为什么? pdf
也是你的罪魁祸首吗? (但你的 EDIT4 对我有用,谢谢!)
您最后的编辑实际上应该是一个答案本身
【参考方案1】:
所有有效的 Unicode 字符都有名称。我们可以检查已识别数字单词 (DIGIT.keys()
) 的名称,并在此基础上用“普通”数字字符 (DIGIT.values()
) 替换给定的 unicode 标签:
import matplotlib.pyplot as plt
import unicodedata as UD
DIGIT =
'MINUS': u'-',
'ZERO': u'0',
'ONE': u'1',
'TWO': u'2',
'THREE': u'3',
'FOUR': u'4',
'FIVE': u'5',
'SIX': u'6',
'SEVEN': u'7',
'EIGHT': u'8',
'NINE': u'9',
'STOP': u'.'
def guess(unistr):
return ''.join([value for u in unistr
for key,value in DIGIT.iteritems()
if key in UD.name(u)])
fig, ax = plt.subplots(1)
ax.plot([-1, 0, 1, 2], range(4))
plt.savefig('/tmp/test.png')
labels = ax.get_xticklabels()
for label in labels:
label = label.get_text()
print(guess(label))
产量
-1.0
-0.5
0.0
0.5
1.0
1.5
2.0
【讨论】:
【参考方案2】:使用plt.xticks()
代替ax.get_xticklabels()
:
import matplotlib.pyplot as plt
fig, ax = plt.subplots(1)
ax.plot([-1, 0, 1, 2], range(4))
plt.savefig('/tmp/test.png')
loc, labels = plt.xticks()
print(type(loc))
# <type 'numpy.ndarray'>
print(loc)
# [-1. -0.5 0. 0.5 1. 1.5 2. ]
【讨论】:
+1 但他们可能实际上是在尝试检查文本标签是否有效 对不起,但这并没有帮助,因为我需要检查的东西,文本标签,与其他情况相同,具有相同的奇怪问题unicode 减号。 @EnricoGiampieri:您希望将标签翻译成哪些有效字符?例如,list('01234567890.-')
是完整列表吗?
是的,在这种情况下,这是预期的列表。以上是关于unicode 减号的转换(来自 matplotlib ticklabels)的主要内容,如果未能解决你的问题,请参考以下文章
在 vc++ 中将 Unicode 字节数组转换为 CString
字符串转换:MBCS <-> UNICODE 内有多个 \0
ANIS与UNICODE字符格式转换:MultiByteToWideChar() 和WideCharToMultiByte() 函数