在 Matplotlib 中绘制子图的问题:第二个图未显示数据

问题描述 投票:0回答:1

我正在尝试在 Matplotlib 中创建子图,其中第一个图是堆积条形图,第二个图是线图。两个图应共享相同的 x 轴日期时间索引。但是,我面临一个问题,第二个图没有显示任何数据。

             Economizer  Economizer_plus_Mech  ...  Not_Mechanical     OaTemp
2023-10-01    1.680672              1.680672  ...        1.680672  84.317815
2023-10-02   17.127072              5.524862  ...        1.657459  76.263536
2023-10-03   31.481481              5.092593  ...        0.000000  73.407407

这是我的绘图函数:

import matplotlib.pyplot as plt
import os
import pandas as pd

PLOTS_DIR = 'path/to/plots'

def save_mode_plot_with_oat(combined_data, title, ylabel, filename):
    # Ensure the index is datetime
    combined_data.index = pd.to_datetime(combined_data.index)

    # Create a 2-row subplot layout, sharing the x-axis
    fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(12, 12), sharex=True)

    # Bar plot for mode percentages on the first subplot
    combined_data.iloc[:, :-1].plot(kind='bar', stacked=True, ax=ax1, colormap='viridis')
    ax1.set_title(title)
    ax1.set_ylabel(ylabel)
    # Hide x-label on the first plot
    ax1.set_xlabel('')
    ax1.tick_params(axis='x', labelbottom=False)  # Hide x-tick labels on the first plot

    # Line plot for outside air temperature on the second subplot
    ax2.plot(combined_data.index, combined_data['OaTemp'], color='red', linestyle='-', marker='o')
    ax2.set_title('Average Outside Air Temperature Over Time')
    ax2.set_ylabel('Average Outside Air Temperature (°F)')
    ax2.set_xlabel('Date')
    ax2.tick_params(axis='x', rotation=90)  # Rotate x-tick labels on the second plot
    ax2.grid(True)

    plt.tight_layout()
    plt.savefig(os.path.join(PLOTS_DIR, filename))
    plt.close()

# Example call
save_mode_plot_with_oat(month_df, 'Mode Percentages and OAT', 'Percentage (%)', 'mode_oat_plot.png')

我的情节是这样的,第二个情节总是空白,我无法弄清楚。任何提示表示赞赏。

enter image description here

python pandas matplotlib
1个回答
0
投票

pandas

DataFrame.plot.bar
API 使用索引作为分类变量对数据进行分组,但绘图的 x 值只是 0 到类别数(负 1)。 IE。
ax1
的 x 刻度的实际值将是
0
31
,而标签是索引的字符串表示形式。

与此相反,

DataFrame.plot.line
API 和
matplotlib.pyplot.plot
API 将 x 刻度值的日期转换为自纪元开始(1970 年 1 月 1 日)以来的天数。

两个轴的 x 刻度的

根本不同。 所以,我们能做些什么? 手动构建其中一张图,而不是使用高级 API。 在这种情况下,我们可以通过堆叠数据框中的每一列并将它们在 x 轴上与纪元开始以来的天数对齐来构建条形图。

import pandas as pd import matplotlib.pyplot as plt from matplotlib import colormaps def save_mode_plot_with_oat(combined_data, title, ylabel, filename): # Ensure the index is datetime, get days since epoch combined_data.index = pd.to_datetime(combined_data.index) epoch_days = (combined_data.index.to_series() - pd.to_datetime('1970-1-1')).dt.days # Create a 2-row subplot layout, sharing the x-axis fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(12, 12), sharex=True) # Bar plot for mode percentages on the first subplot cols = combined_data.columns[:-1] cmap = colormaps.get('viridis') prev_y_vals = 0 # plot each column values as a bar on top of the previous bar values for i, col in enumerate(cols): y_vals = combined_data.loc[:, col] + prev_y_vals ax1.bar(epoch_days, height=y_vals, bottom=prev_y_vals, c=cmap(i)) prev_y_vals = y_vals ax1.set_title(title) ax1.set_ylabel(ylabel) ax1.set_xlabel('') ax1.tick_params(axis='x', labelbottom=False) # Line plot for outside air temperature on the second subplot ax2.plot(combined_data.index, combined_data['OaTemp'], color='red', linestyle='-', marker='o') ax2.set_title('Average Outside Air Temperature Over Time') ax2.set_ylabel('Average Outside Air Temperature (°F)') ax2.set_xlabel('Date') ax2.tick_params(axis='x', rotation=90) # Rotate x-tick labels on the second plot ax2.grid(True) plt.tight_layout() plt.savefig(os.path.join(PLOTS_DIR, filename)) plt.close()
    
© www.soinside.com 2019 - 2024. All rights reserved.