[英]How to change distances between labels on Y axis in pyplot?
我正在绘制 x 轴上的时间和 y 轴上的检查点的“旅行时间”图(检查点只是名称,一个检查点对应一个时间戳)。 绘图本身的代码是:
if checkpoints:
plt.plot_date(timestamps,checkpoints,color = "b",linestyle='solid')
else:
plt.plot_date(timestamps,distances,color = "b",linestyle='solid')
时间戳:小时列表:分钟,检查点:字符串列表,距离:整数列表
由于检查点之间的距离不同,我需要在 y 轴上以不同的间距重新绘制绘图。 我想,这可以通过使用距离数组作为第二个参数来实现,但我不知道应该如何重命名距离标签,以便它们与检查点相对应。
编辑:
使用的数据:
时间戳:它们由命令datetime.strptime(timestamp, "%H:%M")
并收集在一个数组中。 输入数据如下:
4:45 4:48 4:51 4:52 4:53 4:54 4:55 4:56 5:15 5:19 5:24 5:25 5:26 5:28 5:29 5:30 5:33 5:35 5:39 5:40 5:42 5:43 5:44 5:45 5:39 5:40 5:46 5:47 5:48 5:50 5:51 5:52
检查点:字符串数组,长度与时间戳相同。 它们会定期重复以匹配时间戳:
[ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H','A', 'B', 'C', 'D', 'E', 'F', 'G', 'H','A', 'B', 'C', 'D', 'E', 'F', 'G', 'H' ]
距离:类似于检查点,但它们是整数,而不是字符串。
[ 0, 9, 12, 16, 18, 21, 23, 24, 0, 9, 12, 16, 18, 21, 23, 24, 0, 9, 12, 16, 18, 21, 23, 24, 0, 9, 12, 16, 18, 21, 23, 24 ]
生成带有检查点和时间戳的输出:
我不喜欢检查点之间的均匀距离。
我想实现这一点 - 带有距离和时间戳的输出(Y 轴上的数字是与检查点 A 的距离),但带有来自第一个示例的标签:
成功的关键是使用检查点的y轴距离,而不是它们的文本标签。
您在这里需要的数据是:
ts = [
'4:45', '4:48', '4:51', '4:52', '4:53', '4:54', '4:55', '4:56',
'5:15', '5:19', '5:24', '5:25', '5:26', '5:28', '5:29', '5:30',
'5:33', '5:35', '5:39', '5:40', '5:42', '5:43', '5:44', '5:45',
'5:39', '5:40', '5:46', '5:47', '5:48', '5:50', '5:51', '5:52']
chkDist = [0, 9, 12, 16, 18, 21, 23, 24]
chkLbl = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H']
检查点距离和标签没有重复。
让我们从数据转换开始。 使用以下命令生成数据帧:
执行此操作的代码是:
timestamps = pd.DataFrame(np.array(ts).reshape((4, -1)).T,
index=chkDist).apply(pd.to_datetime)
日期部分取自当天,但实际上无关紧要。
还将检查点距离和标签转换为Series :
chkLabels = pd.Series(chkLbl, index=chkDist)
然后生成你的图片如下:
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
fig, ax = plt.subplots(figsize=(6, 4), constrained_layout=True)
plt.plot_date(timestamps, timestamps.index, color='b', linestyle='solid')
ax.xaxis.set_major_locator(mdates.MinuteLocator(byminute=range(0,60,15)))
ax.xaxis.set_major_formatter(mdates.DateFormatter(fmt='%H:%M'))
plt.xticks(rotation=30)
for dist, lbl in chkLabels.iteritems():
plt.text(xLbl, dist, lbl, ha='center', va='center')
ax.set_yticks(chkDist, minor=True)
plt.grid(which='minor', linestyle='--')
plt.grid(which='major')
plt.show()
请注意,时间戳是一个DataFrame ,因此从它的每一列生成单独的行。 我使用MinuteLocator每 15 分钟有x 个标签,并使用DateFormatter来格式化它们。
为了打印检查点标签,我使用了额外的循环,遍历chkLabels并打印每个标签。
但是请注意, plt.text 的文本坐标以数据坐标表示,因此:
最后一步是打印网格。 对于次要线,我使用了set_yticks和y取自chkDist 。 然后我调用plt.grid ,分别为次要线,明确指定线型,并为主要线,使用默认属性。
对于您的数据,我得到以下结果:
请注意,检查点标签有时彼此非常接近(在本例中为G和H )。 因此,如果它们相互重叠,您应该修改代码以仅打印选定的标签,例如通过从chkLabels 中删除一些元素。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.