Display both axes in sorted order for non numerical data

huangapple go评论170阅读模式
英文:

Display both axes in sorted order for non numerical data

问题

如何实现两个轴的正确顺序:

  • 要实现 a-b-c 而不是 c-a-b
  • 要实现 x-y-z 而不是 y-z-x
  1. import matplotlib.pyplot as plt
  2. categories_x = ["c", "a", "b", "c", "b"]
  3. categories_y = ["y", "z", "y", "x", "z"]
  4. plt.scatter(categories_x, categories_y)
  5. plt.show()

Display both axes in sorted order for non numerical data

在Stack Overflow上有很多解决方案,它们依赖于以下两种属性之一:

  1. 数据可以转换为数字,例如("1","0",...)-> 转换为数字
  2. 只有一个轴的顺序不正确 -> 按此轴对两个数组进行排序(这样做的原因是轴刻度按首次出现的顺序排列)

但对于我的示例,这些解决方案都不适用。

我正在寻找一种如何在matplotlib中实现这一目标的解决方案。我知道可能有其他方法来传达相同的信息,或者可能有其他不会出现这个问题的库。

英文:

How to achieve the correct order for both axes:

  • a-b-c instead of c-a-b
  • x-y-z instead of y-z-x
  1. import matplotlib.pyplot as plt
  2. categories_x = ["c", "a", "b", "c", "b"]
  3. categories_y = ["y", "z", "y", "x", "z"]
  4. plt.scatter(categories_x, categories_y)
  5. plt.show()

Display both axes in sorted order for non numerical data

There are a lot of solutions on SO, that rely on either of two properties:

  1. The data can be cast to numerical, e.g. ("1", "0", ...) -> cast to numerical
  2. Only one axis has the wrong order -> sort the two arrays by this axis (the reason why this works is, that the axis-ticks are ordered by first occurrence)

But for my example neither of these solutions work.

I'm looking for a solution, of how to get this to work in matplotlib. I am aware, that there are other probably even better ways to convey the same message, or maybe other libraries that don't have this issue.

答案1

得分: 1

关于使用[tag:pandas]和有序的分类数据,您可以尝试以下代码:

  1. ax = plt.subplot()
  2. X = pd.Categorical(categories_x, ordered=True)
  3. Y = pd.Categorical(categories_y, ordered=True)
  4. ax.scatter(X.codes, Y.codes)
  5. ax.set_xticks(range(len(X.categories)), X.categories)
  6. ax.set_yticks(range(len(Y.categories)), Y.categories)

输出结果如下:

Display both axes in sorted order for non numerical data

英文:

What about using [tag:pandas] and an ordered Categorical?

  1. ax = plt.subplot()
  2. X = pd.Categorical(categories_x, ordered=True)
  3. Y = pd.Categorical(categories_y, ordered=True)
  4. ax.scatter(X.codes, Y.codes)
  5. ax.set_xticks(range(len(X.categories)), X.categories)
  6. ax.set_yticks(range(len(Y.categories)), Y.categories)

Output:

Display both axes in sorted order for non numerical data

答案2

得分: 1

以下是您要翻译的代码部分:

  1. import matplotlib.pyplot as plt
  2. categories_x = ["c", "a", "b", "c", "b"]
  3. categories_y = ["y", "z", "y", "x", "z"]
  4. def axis_to_number(values):
  5. # 可以自定义的映射函数
  6. return {j:i for i, j in enumerate(sorted(set(values))}
  7. map_x = axis_to_number(categories_x)
  8. map_y = axis_to_number(categories_y)
  9. # 现在将原始数组转换为映射值以保持顺序
  10. cx = [map_x[i] for i in categories_x]
  11. cy = [map_y[i] for i in categories_y]
  12. xticks, xticklabels = [x for x in map_x.values()], [x for x in map_x.keys()]
  13. yticks, yticklabels = [y for y in map_y.values()], [y for y in map_y.keys()]
  14. # 绘图
  15. fig, ax = plt.subplots()
  16. ax.plot(cx, cy, 'o')
  17. ax.set_xticks(xticks)
  18. ax.set_xticklabels(xticklabels)
  19. ax.set_yticks(yticks)
  20. ax.set_yticklabels(yticklabels)

希望这有帮助!

英文:

How about simply converting everything to numerical values and playing with the x- and y-ticklabels

  1. import matplotlib.pyplot as plt
  2. categories_x = ["c", "a", "b", "c", "b"]
  3. categories_y = ["y", "z", "y", "x", "z"]
  4. def axis_to_number(values):
  5. # this mapping function can be customized
  6. return {j:i for i, j in enumerate(sorted(set(values)))}
  7. map_x = axis_to_number(categories_x)
  8. map_y = axis_to_number(categories_y)
  9. # now convert the original arrays to the
  10. # mapped values to keep the order
  11. cx = [map_x[i] for i in categories_x]
  12. cy = [map_y[i] for i in categories_y]
  13. xticks, xticklabels = [x for x in map_x.values()], [x for x in map_x.keys()]
  14. yticks, yticklabels = [y for y in map_y.values()], [y for y in map_y.keys()]
  15. # plot
  16. fig, ax = plt.subplots()
  17. ax.plot(cx, cy, 'o')
  18. ax.set_xticks(xticks)
  19. ax.set_xticklabels(xticklabels)
  20. ax.set_yticks(yticks)
  21. ax.set_yticklabels(yticklabels)

Display both axes in sorted order for non numerical data

答案3

得分: 0

我们可以使用排序函数将它们按顺序排列。

  1. import matplotlib.pyplot as plt
  2. categories_x = ["c", "a", "b", "c", "b"]
  3. categories_y = ["y", "z", "y", "x", "z"]
  4. plt.scatter(sorted(categories_x), sorted(categories_y))
  5. plt.show()
英文:

We can use sort function to arrange them in sequence.

  1. import matplotlib.pyplot as plt
  2. categories_x = ["c", "a", "b", "c", "b"]
  3. categories_y = ["y", "z", "y", "x", "z"]
  4. plt.scatter(sorted(categories_x), sorted(categories_y))
  5. plt.show()

答案4

得分: 0

以下是翻译好的代码部分:

  1. import matplotlib.pyplot as plt
  2. categories_x = ["c", "a", "b", "c", "b"]
  3. categories_y = ["y", "z", "y", "x", "z"]
  4. p1 = plt.scatter(sorted(categories_x), sorted(categories_y), c='#00000000')
  5. # p1.set_visible(False)
  6. plt.scatter(categories_x, categories_y)
  7. plt.show()

如果你有大量的数据点并且性能成为问题,你可以考虑使用 sorted(set(categ...))

英文:

You could draw a first scatter with the ordered strings, to get the ticks setup properly, then hide it (or use a transparent color) and draw the actual diagram:

  1. import matplotlib.pyplot as plt
  2. categories_x = ["c", "a", "b", "c", "b"]
  3. categories_y = ["y", "z", "y", "x", "z"]
  4. p1 = plt.scatter(sorted(categories_x),sorted(categories_y),c='#00000000')
  5. # p1.set_visible(False)
  6. plt.scatter(categories_x,categories_y)
  7. plt.show()

You may want to use sorted(set(categ...)) if you have large number of points and performance becomes a concern

huangapple
  • 本文由 发表于 2023年6月5日 19:36:03
  • 转载请务必保留本文链接:https://go.coder-hub.com/76406024.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定