如何在Matplotlib对数图中禁用科学计数法坐标轴标签?
如何去除Matplotlib对数x轴的科学计数法标注?
我需要移除x轴上所有类似3x10^-6的科学计数法标注,这些标注打乱了x轴标签的布局。当前我的绘图代码片段如下:
ticks = [0.00005, 0.0001, 0.0002, 0.0005] ax.set_title(f'Period {period} days') ax.set_xlabel('Volatility (EWMA)') ax.set_xscale('log') ax.set_ylabel('mean[S_365/S_0/RF_0]') ax.grid(True) # Force fixed ticks ax.set_xticks(ticks) ax.set_xlim([ticks[0], ticks[-1]]) ax.xaxis.set_major_formatter(FuncFormatter(lambda x, _: f'{x:.4f}'))
我尝试了网上各种方法的变体,但都没有效果。以下是可复现代例:
import pandas as pd import matplotlib.pyplot as plt import numpy as np from matplotlib.ticker import FuncFormatter np.random.seed(0) def make_data(): data = [] for period_d in [182, 365]: # Log-spaced ema_var_d_t between 0.00005 and 0.0005 (as before) ema_vars = 10 ** np.random.uniform(np.log10(0.00005), np.log10(0.0005), 500) # Increase standard deviation of lr_t2 for meaningful spread for ema_var in ema_vars: lr_t2 = np.random.normal(0, 0.2) # Increased from 0.05 to 0.2 lr_rf_1y_t = np.log(1.02) data.append({ 'period_d': period_d, 'lr_t2': lr_t2, 'lr_rf_1y_t': lr_rf_1y_t, 'ema_var_d_t': ema_var }) df = pd.DataFrame(data) df['nlr_t2'] = df['lr_t2'] - df['lr_rf_1y_t'] df['nr_t2'] = np.exp(df['nlr_t2']) return df df = make_data() def plot_all_periods(df, window = 5): unique_periods = df['period_d'].unique() n = len(unique_periods) cols = 3 rows = (n + cols - 1) // cols fig, axes = plt.subplots(rows, cols, figsize=(5 * cols, 4 * rows), squeeze=False) for idx, period in enumerate(unique_periods): ax = axes[idx // cols][idx % cols] df_period = df[df['period_d'] == period].sort_values('ema_var_d_t').reset_index(drop=True) result_x = [] result_y = [] for i in range(len(df_period)): left = i - window right = i + window if left < 0 or right >= len(df_period): continue avg = np.mean(df_period['nr_t2'].iloc[left:right+1]) result_x.append(df_period['ema_var_d_t'].iloc[i]) result_y.append(avg) ax.plot(result_x, result_y, linewidth=2) ticks = [0.00005, 0.0001, 0.0002, 0.0005] ax.set_title(f'Period {period} days') ax.set_xlabel('Volatility (EWMA)') ax.set_xscale('log') ax.set_ylabel('mean[S_365/S_0/RF_0]') ax.grid(True) # Force fixed ticks ax.set_xticks(ticks) ax.set_xlim([ticks[0], ticks[-1]]) ax.xaxis.set_major_formatter(FuncFormatter(lambda x, _: f'{x:.4f}')) # Hide empty subplots for idx in range(n, rows * cols): fig.delaxes(axes[idx // cols][idx % cols]) plt.tight_layout() plt.show() plot_all_periods(df)
解决方案
问题出在对数刻度的次要刻度上:你已经设置了主刻度的格式化,但Matplotlib默认会在对数轴上显示次要刻度,这些次要刻度使用科学计数法标注,导致布局混乱。
方法1:隐藏次要刻度(推荐)
在设置主刻度的代码后,添加一行代码清除次要刻度的显示:
# 清除次要刻度的标签和刻度线 ax.set_xticks([], minor=True)
修改后的关键代码段:
# Force fixed ticks ax.set_xticks(ticks) ax.set_xlim([ticks[0], ticks[-1]]) ax.xaxis.set_major_formatter(FuncFormatter(lambda x, _: f'{x:.4f}')) # 隐藏次要刻度 ax.set_xticks([], minor=True)
方法2:格式化次要刻度(如果需要保留)
如果你想保留次要刻度但统一格式,可以给次要刻度也设置格式化器:
ax.xaxis.set_minor_formatter(FuncFormatter(lambda x, _: f'{x:.5f}'))
不过这种方式可能会导致x轴标签过于密集,影响可读性,因此更推荐方法1。
内容的提问来源于stack exchange,提问作者Alex Craft
相关产品推荐
相关产品推荐

