【问题标题】:Synchronizing twinx y-axis based on two lines基于两条线同步 twinx y 轴
【发布时间】:2022-01-14 19:30:40
【问题描述】:

我的最终目标是创建一个图表,该图表可以快速传达两个数据点位于各自的界限之间。我可以创建两个单独的图表,而不是将这些信息放在一个图表上;图表数据并用水平线说明边界。如果我可以让这个基本功能用一张图来完成,那就更优雅了。

有什么方法可以用来同步两个y-axes,以便y-axis 1 上的某个值A1y-axis 2 上的A2 垂直出现在图表中的同一位置,而在同时,确保y-axis 1 上的另一个特定值B1y-axis 2 上的B2 出现在图表中垂直的单独不同位置?

import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
import datetime

### Generate linear data
Temp = 20
pH = 6
DataCopy = pd.DataFrame({'Temp': [], 'pH': [], 'Time': []})
for i in range(10):
    DataTime = datetime.datetime.now()
    DataCopy = DataCopy.append({'Temp': Temp, 'pH': pH, 'Time': DataTime}, ignore_index=True)
    Temp += (-0.5)
    pH   += (0.2)

### Plot data unto graph w/ double y-axis
sns.lineplot(data=DataCopy, x='Time', y='pH', color = 'red', label = 'Temp')
ax2 = plt.twinx()
sns.lineplot(data=DataCopy, x='Time', y='Temp', color = 'blue', label = 'pH', ax=ax2)
plt.legend()
plt.show() 

如果在单独的图表上完成此实现的外观:

想要的效果:

【问题讨论】:

    标签: python matplotlib seaborn


    【解决方案1】:

    您似乎想将左轴上的两个位置与右轴上的两个位置对齐。

    以下方法测量两个轴的下限与两条线的距离因子。然后它将最大因子应用于具有最低因子的轴。模拟发生在轴的上限。

    import matplotlib.pyplot as plt
    import seaborn as sns
    import pandas as pd
    import numpy as np
    
    np.random.seed(2021)
    ph_low, ph_high = 7, 9
    temp_low, temp_high = 12, 18
    
    data_copy = pd.DataFrame({'Temp': np.random.normal(0.04, 0.4, 100).cumsum() + 10,
                              'pH': np.random.normal(0.02, 0.2, 100).cumsum() + 6,
                              'Time': pd.date_range('20211211 08:00:00', freq='1min', periods=100)})
    
    plt.figure(figsize=(12, 5))
    ax1 = sns.lineplot(data=data_copy, x='Time', y='pH', color='red', label='Temp')
    ax1.axhline(ph_low, color='red', ls=(0, (5, 5, 0)))
    ax1.axhline(ph_high, color='red', ls=(0, (5, 5, 0)))
    
    ax2 = ax1.twinx()
    sns.lineplot(data=data_copy, x='Time', y='Temp', color='blue', label='pH', ax=ax2)
    ax2.axhline(temp_low, color='blue', ls=(0, (0, 5, 5)))
    ax2.axhline(temp_high, color='blue', ls=(0, (0, 5, 5)))
    
    handles1, labels1 = ax1.get_legend_handles_labels()
    handles2, labels2 = ax2.get_legend_handles_labels()
    ax1.legend_.remove()
    ax2.legend(handles=handles1 + handles2, labels=labels1 + labels2)
    
    ymin1, ymax1 = ax1.get_ylim()
    ymin2, ymax2 = ax2.get_ylim()
    
    fymin1 = (ph_low - ymin1) / (ph_high - ph_low)
    fymin2 = (temp_low - ymin2) / (temp_high - temp_low)
    if fymin1 < fymin2:  # move ymin1 using fymin2
        ymin1 = ph_low - fymin2 * (ph_high - ph_low)
    else:  # move ymin2 using fymin1
        ymin2 = temp_low - fymin1 * (temp_high - temp_low)
    
    fymax1 = (ymax1 - ph_high) / (ph_high - ph_low)
    fymax2 = (ymax2 - temp_high) / (temp_high - temp_low)
    if fymax1 < fymax2:  # move ymax1 using fymax2
        ymax1 = ph_high + fymax2 * (ph_high - ph_low)
    else:  # move ymax2 using fymax1
        ymax2 = temp_high + fymax1 * (temp_high - temp_low)
    
    ax1.set_ylim(ymin1, ymax1)
    ax2.set_ylim(ymin2, ymax2)
    
    plt.show()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-09-08
      • 2021-03-16
      • 1970-01-01
      • 2016-09-24
      • 1970-01-01
      • 1970-01-01
      • 2017-07-31
      相关资源
      最近更新 更多