如何以自定义顺序使用 yticklabels 创建散点图
How to create a scatter plot with yticklabels in a custom order
我可以这样做并产生散点图吗?
y-axis tick/label order → [0, 7, 2, 9, 4, 11, 6, 1, 8, 3, 10, 5]
x = ('a', 'b', 'c', 'd', 'e')
y = [[1,5,2], [10,5,11,7], [9], [], [ 7, 2, 9, 4, 11, 6, 1, 8, 3, 10, 5]]
想法是将 x 值映射到 y 值。例如数据列表中的第一个 ('a'
) 是在目标上击中 1、5 和 2,第二个 ('b'
) 击中分数 10、5、11、7。我需要按照显示的顺序将 Y 轴作为标签。
实现包括按照 y_ticks
定义的顺序获取 y 轴 ticklabels
,这需要将 yticklabels
更改为与默认 ytick 坐标不匹配的内容。
import matplotlib.pyplot as plt
# Define the data we'll work with.
x_labels = ("a", "b", "c", "d", "e")
x_ticks = range(len(x_labels))
y_ticks = (0, 7, 2, 9, 4, 11, 6, 1, 8, 3, 10, 5)
# y values to be plotted
y_lists = ([1, 5 , 2], [10, 5, 11, 7], [9], [], [7, 2, 9, 4, 11, 6, 1, 8, 3, 10, 5])
# Define the figure and ax.
fig, ax = plt.subplots()
fig.show()
# Disable y-autoscaling since we are defining the ticks and ticklabels ourselves.
ax.autoscale(False)
# We can use a bit of custom padding.
e = 0.05
xmin, xmax = min(x_ticks), max(x_ticks)
dx = xmax - xmin
ax.set_xlim(xmin - dx*e, xmax + dx*e)
ymin, ymax = min(y_ticks), max(y_ticks)
dy = ymax - ymin
ax.set_ylim(ymin - dy*e, ymax + dy*e)
# Set the sorted y-ticks.
ax.set_yticks(sorted(y_ticks))
ax.set_yticklabels(y_ticks)
# Set the x-ticks.
ax.set_xticks(x_ticks)
ax.set_xticklabels(x_labels) # `ax.set_xticklabels("abcde")` would work too.
for x, y_list in zip(x_ticks, y_lists):
# We have a single x value for each letter, but we need the x-list to be as long y-list in order to make a scatter.
x_list = [x]*len(y_list)
# Notice the use of `.index` here to accommodate the ticks not being ordered.
true_y_list = [y_ticks.index(y) for y in y_list]
ax.scatter(x_list, true_y_list)
对于使用 dict
保存数据并在其键后自动命名 x-ticks 的变体,我们可以将第一段替换为:
# Define the data we'll work with.
data = {"a": [1, 5 , 2],
"b": [10, 5, 11, 7],
"c": [9],
"d": [],
"e": [7, 2, 9, 4, 11, 6, 1, 8, 3, 10, 5]}
x_labels = data.keys()
x_ticks = range(len(x_labels))
y_ticks = (0, 7, 2, 9, 4, 11, 6, 1, 8, 3, 10, 5)
y_lists = data.values()
我可以这样做并产生散点图吗?
y-axis tick/label order → [0, 7, 2, 9, 4, 11, 6, 1, 8, 3, 10, 5]
x = ('a', 'b', 'c', 'd', 'e')
y = [[1,5,2], [10,5,11,7], [9], [], [ 7, 2, 9, 4, 11, 6, 1, 8, 3, 10, 5]]
想法是将 x 值映射到 y 值。例如数据列表中的第一个 ('a'
) 是在目标上击中 1、5 和 2,第二个 ('b'
) 击中分数 10、5、11、7。我需要按照显示的顺序将 Y 轴作为标签。
实现包括按照 y_ticks
定义的顺序获取 y 轴 ticklabels
,这需要将 yticklabels
更改为与默认 ytick 坐标不匹配的内容。
import matplotlib.pyplot as plt
# Define the data we'll work with.
x_labels = ("a", "b", "c", "d", "e")
x_ticks = range(len(x_labels))
y_ticks = (0, 7, 2, 9, 4, 11, 6, 1, 8, 3, 10, 5)
# y values to be plotted
y_lists = ([1, 5 , 2], [10, 5, 11, 7], [9], [], [7, 2, 9, 4, 11, 6, 1, 8, 3, 10, 5])
# Define the figure and ax.
fig, ax = plt.subplots()
fig.show()
# Disable y-autoscaling since we are defining the ticks and ticklabels ourselves.
ax.autoscale(False)
# We can use a bit of custom padding.
e = 0.05
xmin, xmax = min(x_ticks), max(x_ticks)
dx = xmax - xmin
ax.set_xlim(xmin - dx*e, xmax + dx*e)
ymin, ymax = min(y_ticks), max(y_ticks)
dy = ymax - ymin
ax.set_ylim(ymin - dy*e, ymax + dy*e)
# Set the sorted y-ticks.
ax.set_yticks(sorted(y_ticks))
ax.set_yticklabels(y_ticks)
# Set the x-ticks.
ax.set_xticks(x_ticks)
ax.set_xticklabels(x_labels) # `ax.set_xticklabels("abcde")` would work too.
for x, y_list in zip(x_ticks, y_lists):
# We have a single x value for each letter, but we need the x-list to be as long y-list in order to make a scatter.
x_list = [x]*len(y_list)
# Notice the use of `.index` here to accommodate the ticks not being ordered.
true_y_list = [y_ticks.index(y) for y in y_list]
ax.scatter(x_list, true_y_list)
对于使用 dict
保存数据并在其键后自动命名 x-ticks 的变体,我们可以将第一段替换为:
# Define the data we'll work with.
data = {"a": [1, 5 , 2],
"b": [10, 5, 11, 7],
"c": [9],
"d": [],
"e": [7, 2, 9, 4, 11, 6, 1, 8, 3, 10, 5]}
x_labels = data.keys()
x_ticks = range(len(x_labels))
y_ticks = (0, 7, 2, 9, 4, 11, 6, 1, 8, 3, 10, 5)
y_lists = data.values()