如何移除Matplotlib中x轴的空坐标 解决重复名称绘图异常问题
修正后可运行代码
import pandas as pd import numpy as np from matplotlib import pyplot as plt import matplotlib.ticker as ticker data = {'Name': ['Status', 'Status', 'HMI', 'Allst', 'Drvr', 'CurrTUBand', 'RUSource', 'RUReqstrPriority', 'RUReqstrSystem', 'RUResReqstStat', 'CurrTUBand', 'DSP', 'SetDSP', 'SetDSP', 'DSP', 'RUSource', 'RUReqstrPriority', 'RUReqstrSystem', 'RUResReqstStat', 'Status', 'Delay', 'Status', 'Delay', 'HMI', 'Status', 'Status', 'HMI', 'DSP'], 'Value': [4, 4, 2, 1, 1, 1, 0, 7, 0, 4, 1, 1, 3, 0, 3, 0, 7, 0, 4, 1, 0, 1, 0, 1, 4, 4, 2, 3], 'Id_Par': [0, 0, 0, 0, 0, 0, 10, 10, 10, 10, 10, 0, 0, 22, 22, 28, 28, 28, 28, 0, 0, 38, 38, 0, 0, 0, 0, 0] } signals_df = pd.DataFrame(data) def plot_signals(signals_df): # Count signals by parallel signals_df['Count'] = signals_df.groupby('Id_Par').cumcount().add(1).mask(signals_df['Id_Par'].eq(0), 0) # Subtract Parallel values from the index column signals_df['Sub'] = signals_df.index - signals_df['Count'] id_par_prev = signals_df['Id_Par'].unique() id_par = np.delete(id_par_prev, 0) signals_df['Prev'] = [1 if x in id_par else 0 for x in signals_df['Id_Par']] signals_df['Final'] = signals_df['Prev'] + signals_df['Sub'] # 按计算后的Final索引排序后重置连续索引作为绘图x轴位置 signals_df.sort_values('Final', inplace=True) signals_df.reset_index(drop=True, inplace=True) # 记录原始Final索引作为x轴刻度标签 x_labels = signals_df['Final'].values.tolist() # 识别需要加黄色阴影的跳过区间 skip_intervals = [] current_par = None start_idx = None for idx, row in signals_df.iterrows(): if row['Id_Par'] != 0: if current_par is None: current_par = row['Id_Par'] start_idx = idx else: if current_par is not None: skip_intervals.append((start_idx-0.5, idx-0.5)) current_par = None if current_par is not None: skip_intervals.append((start_idx-0.5, len(signals_df)-0.5)) # Get individual names and variables for the chart names_list = [name for name in signals_df['Name'].unique()] num_names_list = len(names_list) # Creation Graphics fig, ax = plt.subplots(nrows=num_names_list, figsize=(10, 10), sharex=True) plt.xticks(color='SteelBlue', fontweight='bold') # 用连续数值作为x轴位置,手动设置刻度标签避免分类轴乱序问题 x_pos = np.arange(len(signals_df)) plt.xticks(x_pos, labels=[str(i) for i in x_labels]) for pos, (a_, name) in enumerate(zip(ax, names_list)): # 绘制跳过区域黄色阴影 for (start, end) in skip_intervals: a_.axvspan(start, end, color='yellow', alpha=0.3) # Get data data = signals_df[signals_df["Name"] == name]["Value"] # Get values axis-x and axis-y x_ = np.hstack([-1, data.index.values, len(signals_df)]) y_ = np.hstack([0, data.values, data.iloc[-1]]) # 直接用数值x轴绘图 a_.plot(x_, y_, drawstyle='steps-post', marker='*', markersize=8, color='k', linewidth=2) a_.set_ylabel(name, fontsize=8, fontweight='bold', color='SteelBlue', rotation=30, labelpad=35) a_.yaxis.set_major_formatter(ticker.FormatStrFormatter('%0.1f')) a_.yaxis.set_tick_params(labelsize=6) a_.grid(alpha=0.4, color='SteelBlue') # 标注数值 for i in range(len(y_)-1): xy = [x_[i], y_[i]] a_.text(x=xy[0], y=xy[1], s=str(xy[1]), color='k', fontweight='bold', fontsize=12) plt.xlim(-0.5, len(signals_df)-0.5) plt.tight_layout() plt.show() plot_signals(signals_df)
核心改动说明
- 修复了原代码未定义变量
all_names_list的语法错误 - 放弃将x值转为字符串的分类轴方案,改用连续数值作为x轴位置,手动映射原始Final索引作为刻度标签,彻底避免x轴值重复导致的顺序错乱
- 新增了跳过区间的黄色阴影绘制逻辑,自动识别
Id_Par非0的并行区间添加半透明黄色背景 - 调整了x轴范围和文本标注逻辑,避免标注错位
- 对dataframe按Final索引排序后重置了连续数值索引,避免绘图时索引跳跃导致的图形异常
内容的提问来源于stack exchange,提问作者MayEncoding
相关产品推荐
相关产品推荐

