Python NLTK文本离散图的y垂直轴为向后/反向顺序

kmbjn2e3  于 2023-10-14  发布在  Python
关注(0)|答案(2)|浏览(125)

从上个月开始,NLTK dispersion_plot似乎在我的机器上有y(垂直)轴的颠倒顺序。这可能与我的软件版本有关(我在学校的虚拟机上)。
版本:nltk 3.8.1 matplotlib 3.7.2 Python 3.9.13
验证码:

  1. from nltk.draw.dispersion import dispersion_plot
  2. words=['aa','aa','aa','bbb','cccc','aa','bbb','aa','aa','aa','cccc','cccc','cccc','cccc']
  3. targets=['aa','bbb', 'f', 'cccc']
  4. dispersion_plot(words, targets)

预期:在开始时,有一个人在场,在结束时,有一个人在场。实际:它是向后的!还注意,F应该完全不存在,而不是BBB不存在。
结论:Y轴向后。

46qrfjad

46qrfjad1#

我发现源代码nltk.draw.dispersion,似乎有错误。

  1. def dispersion_plot(text, words, ignore_case=False, title="Lexical Dispersion Plot"):
  2. """
  3. Generate a lexical dispersion plot.
  4. :param text: The source text
  5. :type text: list(str) or iter(str)
  6. :param words: The target words
  7. :type words: list of str
  8. :param ignore_case: flag to set if case should be ignored when searching text
  9. :type ignore_case: bool
  10. :return: a matplotlib Axes object that may still be modified before plotting
  11. :rtype: Axes
  12. """
  13. try:
  14. import matplotlib.pyplot as plt
  15. except ImportError as e:
  16. raise ImportError(
  17. "The plot function requires matplotlib to be installed. "
  18. "See https://matplotlib.org/"
  19. ) from e
  20. word2y = {
  21. word.casefold() if ignore_case else word: y
  22. for y, word in enumerate(reversed(words)) # <--- HERE
  23. }
  24. xs, ys = [], []
  25. for x, token in enumerate(text):
  26. token = token.casefold() if ignore_case else token
  27. y = word2y.get(token)
  28. if y is not None:
  29. xs.append(x)
  30. ys.append(y)
  31. _, ax = plt.subplots()
  32. ax.plot(xs, ys, "|")
  33. ax.set_yticks(list(range(len(words))), words, color="C0") # <--- HERE
  34. ax.set_ylim(-1, len(words))
  35. ax.set_title(title)
  36. ax.set_xlabel("Word Offset")
  37. return ax
  38. if __name__ == "__main__":
  39. import matplotlib.pyplot as plt
  40. from nltk.corpus import gutenberg
  41. words = ["Elinor", "Marianne", "Edward", "Willoughby"]
  42. dispersion_plot(gutenberg.words("austen-sense.txt"), words)
  43. plt.show()

它使用reversed(words)计算word2y

  1. for y, word in enumerate(reversed(words))

但后来它使用ax.set_yticks()使用words但它应该使用reversed(words)

  1. ax.set_yticks(list(range(len(words))), words, color="C0")

(or它应该计算word2y而不使用reversed())。
我在上面的代码中添加了# <--- HERE来显示这些地方。
它可能需要将其作为一个问题报告。
此时,您可以获取ax并使用set_yticksreversed来纠正它。
在您的代码中,它将是targets而不是words

  1. ax = dispersion_plot(words, targets)
  2. ax.set_yticks(list(range(len(targets))), reversed(targets), color="C0")

完整工作代码

  1. import matplotlib.pyplot as plt
  2. from nltk.draw.dispersion import dispersion_plot
  3. words = ['aa','aa','aa','bbb','cccc','aa','bbb','aa','aa','aa','cccc','cccc','cccc','cccc']
  4. targets = ['aa','bbb', 'f', 'cccc']
  5. ax = dispersion_plot(words, targets)
  6. ax.set_yticks(list(range(len(targets))), reversed(targets), color="C0")
  7. plt.show()

**编辑:**我似乎这个问题是几个月前报告的,他们在GitHub上的代码中添加了reversed()-可能它会在下一个版本中工作

dispersion plot not working properly · Issue #3133 · nltk/nltk
dispersion plot not working properly by Apros7 · Pull Request #3134 · nltk/nltk

展开查看全部
lnvxswe2

lnvxswe22#

基于@furas的答案️,我进一步添加了一个if条件,只有当y ticks确实被打破/向后时才反转它们。这意味着一旦他们修复了库错误(这意味着很快),代码仍然可以工作。

  1. from nltk.draw.dispersion import dispersion_plot
  2. targets=['a', 'b']
  3. filtered_text = ["a","a","b"]
  4. my_plot = dispersion_plot(filtered_text, targets, ignore_case=True)
  5. # THIS IS NEW: if targets are wrong, fix them (reverse them)
  6. if [label.get_text() for label in my_plot.get_yticklabels()] != reversed(targets):
  7. my_plot.set_yticks(list(range(len(targets))), reversed(targets))
  8. plt.show()

(我在本地修复了图形库,并使用新版本进行了测试,代码可以在旧的坏库和新修复的库上工作)x1c 0d1x

相关问题