Python,Matplotlib:规范化多个图以适应相同的任意轴限制

Python, Matplotlib: Normalising multiple plots to fit the same arbitrary axis limits

我正在尝试创建一个包含多个图的图形,并将它们全部归一化,以便可以轻松区分它们的特征。我在表达我正在尝试做的事情时遇到了一些问题,但下面的示例代码应该有助于澄清。

由以下代码生成的示例图。

代码创建了一个包含三行的图形。黑线的数据在 -1000 到 1000 之间变化,因此比例会相应调整。这意味着很难看到绿色数据的变化,甚至红色数据的变化。理想情况下,我想放大绿色和红色数据,以便它们的变化更清晰——但希望不要只乘以一个常数值。

我希望的结果示例 - 不同的线都具有不同的数量级,但已适合任意 y 轴刻度,因此可以展示它们的形状。

import numpy as np
import matplotlib.pyplot as plt

time_arr = np.arange(0, 25, 1)

dist_arr = np.zeros(len(time_arr))
speed_arr = np.zeros(len(time_arr))
energy_arr = np.zeros(len(time_arr))

for i in range(len(time_arr)):
    dist_arr[i] = np.random.randint(-10, 10)
    speed_arr[i] = np.random.randint(-50, 50)
    energy_arr[i] = np.random.randint(-1000, 1000)


fig = plt.figure(figsize=(13,13))

plt.plot(time_arr, dist_arr, 'red', linestyle='-', label='dist (m)', linewidth=5)
plt.plot(time_arr, speed_arr, 'lime', linestyle='-', label='speed (m/s)', linewidth=5)
plt.plot(time_arr, energy_arr, 'black', linestyle='--', label='E_tot (J)', linewidth=5)

plt.xlabel('Time (s)', fontsize=25)
plt.ylabel('Various Params', fontsize=25)
plt.tick_params(axis='x', labelsize=20)
plt.tick_params(axis='y', labelsize=20)
plt.title('Various VS Time', fontsize = 32, y=1.008)
plt.legend(loc='best', fontsize=25)

plt.show()

我试过为每个单独的线图使用 plt.ylim([0, 100]) 之类的东西,但这似乎没有成功。这里的任何帮助都会很棒,干杯。

编辑:

感谢 ImportanceOfBeingErnest 改进的规范化技术以及已接受的答案,问题在评论中得到了解决。谢谢!

我想你有两个选择:

  1. 子图 - see this demo。你可以复制 "sharing both axes" case

  2. 双 y 轴 - see here。我认为这些图不太清楚,因为很难看出每条曲线使用哪个比例尺。

我会推荐选项 1

您可以选择对数据进行归一化,也可以使用多个双 y 轴。见下文。

import numpy as np
import matplotlib.pyplot as plt

def norm(data):
    return (data)/(max(data)-min(data))

time_arr = np.arange(0, 25, 1)

dist_arr = np.zeros(len(time_arr))
speed_arr = np.zeros(len(time_arr))
energy_arr = np.zeros(len(time_arr))

for i in range(len(time_arr)):
    dist_arr[i] = np.random.randint(-10, 10)
    speed_arr[i] = np.random.randint(-50, 50)
    energy_arr[i] = np.random.randint(-1000, 1000)

# option 1
fig = plt.figure(figsize=(10,10))

plt.plot(time_arr, norm(dist_arr), 'red', linestyle='-', label='dist (m)', linewidth=5)
plt.plot(time_arr, norm(speed_arr), 'lime', linestyle='-', label='speed (m/s)', linewidth=5)
plt.plot(time_arr, norm(energy_arr), 'black', linestyle='--', label='E_tot (J)', linewidth=5)

plt.xlabel('Time (s)', fontsize=25)
plt.ylabel('Various Params', fontsize=25)
plt.tick_params(axis='x', labelsize=20)
plt.tick_params(axis='y', labelsize=20)
plt.title('Various VS Time', fontsize = 32, y=1.008)
plt.legend(loc='best', fontsize=25)

plt.show()

# option 2
fig, ax1 = plt.subplots(1,1,figsize=(12,9))

ax1.plot(time_arr, dist_arr, 'red', linestyle='-', label='dist (m)', linewidth=5)
ax1.set_xlabel('Time (s)', fontsize=25)
# Make the y-axis label, ticks and tick labels match the line color.
ax1.set_ylabel('Distance(m)', color='r',fontsize=25)
ax1.tick_params('y', colors='r', labelsize=20)

ax2 = ax1.twinx()
ax2.plot(time_arr, speed_arr, 'lime', linestyle='-', label='speed (m/s)', linewidth=5)
ax2.set_ylabel('Speed (m/s)', color='lime',fontsize=25)
ax2.tick_params('y', colors='lime', labelsize=20)

ax3 = ax1.twinx()
ax3.spines['right'].set_position(('axes', 1.25)) # move the right axis light bit to the right by 25 % of the axes
ax3.plot(time_arr, norm(energy_arr), 'black', linestyle='--', label='E_tot (J)', linewidth=5)
ax3.set_ylabel('E_tot (J)', color='black',fontsize=25)
ax3.tick_params('y', colors='black', labelsize=20)


fig.tight_layout()
plt.show()

结果

您应该在分子中包含 (data -np.amin(x)) 以正确重新缩放。