You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 02:22:04