我遇到了matplotlib用来表示ticklabels的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'
但是这比解决方案更多而且破解,我几乎可以肯定它在不同系统中不稳定,所以我希望更接近解决方案。
我正在使用
在Kubuntu 12.10上。
非常感谢你的帮助!
更正了情节的顺序,因为我得到了x和y倒置,抱歉
此链接中包含类似信息:http://www.coniferproductions.com/2012/12/17/unicode-character-dump-in-python/
最后它显示了在某些书中使用的减号是一个更令人愉快的减号,但是python解释器没有将其识别为有效字符。
所以,我使用的简单替换实际上是正确的实际操作,但“道德上”是python(2.7和3.x等)中的一个错误,它不能识别减号的正确符号。 / p>
查看http://bugs.python.org/issue6632
中的错误跟踪要禁用此行为,matplotlib上有一个简单的解决方案,只需在.matplotlibrc中或以编程方式修改rcparams。
import matplotlib as mpl
mpl.rcParams['axes.unicode_minus']=False
答案 0 :(得分:1)
使用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 :(得分:0)
所有有效的unicode字符都有名称。我们可以检查已识别的数字(DIGIT.keys()
)的名称,并在此基础上用给定的unicode标签替换“普通”数字字符(DIGIT.values()
):
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