matplotlib 使用者警告:FixedFormatter只能与FixedLocator一起使用

uttx8gqw  于 2022-12-13  发布在  其他
关注(0)|答案(8)|浏览(418)

很长一段时间以来,我一直使用小的子程序来格式化我正在绘制的图表的轴。下面是几个例子:

def format_y_label_thousands(): # format y-axis tick labels formats
    ax = plt.gca()
    label_format = '{:,.0f}'
    ax.set_yticklabels([label_format.format(x) for x in ax.get_yticks().tolist()])

def format_y_label_percent(): # format y-axis tick labels formats
    ax = plt.gca()
    label_format = '{:.1%}'
    ax.set_yticklabels([label_format.format(x) for x in ax.get_yticks().tolist()])

然而,在昨天更新matplotlib之后,当调用这两个函数中的任何一个时,我得到以下警告:

UserWarning: FixedFormatter should only be used together with FixedLocator
  ax.set_yticklabels([label_format.format(x) for x in ax.get_yticks().tolist()])

为什么会出现这样的警告?我在查看matplotlib的文档时无法理解。

fjaof16o

fjaof16o1#

解决方法:

避免警告的方法是使用FixedLocator(这是matplotlib.ticker的一部分)。下面我展示了绘制三个图表的代码。我以不同的方式格式化它们的坐标轴。注意“set_ticks”使警告静音,但它会更改实际的刻度位置/标注(我花了一些时间才弄清楚FixedLocator使用相同的信息,但保持滴答位置完整)。您可以使用x/y's以查看每个解决方案可能如何影响输出。

import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.ticker as mticker

mpl.rcParams['font.size'] = 6.5

x = np.array(range(1000, 5000, 500))
y = 37*x

fig, [ax1, ax2, ax3] = plt.subplots(1,3)

ax1.plot(x,y, linewidth=5, color='green')
ax2.plot(x,y, linewidth=5, color='red')
ax3.plot(x,y, linewidth=5, color='blue')

label_format = '{:,.0f}'

# nothing done to ax1 as it is a "control chart."

# fixing yticks with "set_yticks"
ticks_loc = ax2.get_yticks().tolist()
ax2.set_yticks(ax1.get_yticks().tolist())
ax2.set_yticklabels([label_format.format(x) for x in ticks_loc])

# fixing yticks with matplotlib.ticker "FixedLocator"
ticks_loc = ax3.get_yticks().tolist()
ax3.yaxis.set_major_locator(mticker.FixedLocator(ticks_loc))
ax3.set_yticklabels([label_format.format(x) for x in ticks_loc])

# fixing xticks with FixedLocator but also using MaxNLocator to avoid cramped x-labels
ax3.xaxis.set_major_locator(mticker.MaxNLocator(3))
ticks_loc = ax3.get_xticks().tolist()
ax3.xaxis.set_major_locator(mticker.FixedLocator(ticks_loc))
ax3.set_xticklabels([label_format.format(x) for x in ticks_loc])

fig.tight_layout()
plt.show()

输出图表:

很明显,像上面这样有几行空闲代码(我基本上是获取yticks或xticks并重新设置它们)只会给我的程序增加噪音。我更希望警告被删除。但是,看看一些“bug报告”(来自上面/下面评论中的链接;这个问题实际上并不是一个bug:这是一个更新,产生了一些问题),管理matplotlib的贡献者有他们的理由保留警告。

**旧版本的matplotLIB:**如果你使用控制台来控制代码的关键输出(就像我一样),警告消息可能会有问题。因此,推迟处理这个问题的一种方法是将matplotlib降级到3.2.2版本。我使用Anaconda来管理我的Python包,下面是降级matplotlib的命令:

conda install matplotlib=3.2.2

并非所有列出的版本都可用。例如,无法安装matplotlib 3.3.0,尽管它在matplotlib的发布页面上列出:https://github.com/matplotlib/matplotlib/releases

rm5edbpk

rm5edbpk2#

如果有人使用函数axes.xaxis.set_ticklabels()(或y轴等效函数)进入此处,则不需要使用FixedLocator,可以使用axes.xaxis.set_ticks(values_list)BEFOREaxes.xaxis.set_ticklabels(labels_list)来避免此警告。

mu0hgdu0

mu0hgdu03#

根据此matplotlib page

# FixedFormatter should only be used together with FixedLocator. 
# Otherwise, one cannot be sure where the labels will end up.

这意味着一个人应该做

positions = [0, 1, 2, 3, 4, 5]
labels = ['A', 'B', 'C', 'D', 'E', 'F']
ax.xaxis.set_major_locator(ticker.FixedLocator(positions))
ax.xaxis.set_major_formatter(ticker.FixedFormatter(labels))

但是,即使标签被传递到ticker.FixedFormatterticker.LogLocator也会存在这个问题。
1.定义格式化程序函数

# FuncFormatter can be used as a decorator
@ticker.FuncFormatter
def major_formatter(x, pos):
    return f'{x:.2f}'

1.并将格式化程序函数传递给FixedFormatter

ax.xaxis.set_major_locator(ticker.LogLocator(base=10, numticks=5))
ax.xaxis.set_major_formatter(major_formatter)

详情请参见上面的链接。

krugob8w

krugob8w4#

当我尝试在X轴上旋转带有已定位日期刻度的刻度标签时,遇到了同样的问题:

ax.set_xticklabels(ax.get_xticklabels(), rotation=45)
ax.xaxis.set_major_locator(dates.DayLocator())

它使用'tick_params()'方法计算得出:

ax.tick_params(axis='x', labelrotation = 45)
q43xntqr

q43xntqr5#

最简单的解决方法是抑制警告(这包括UserWarning):

import warnings
warnings.filterwarnings("ignore")

如果你不想让github上的jupyter笔记本看起来像垃圾一样被警告信息所困扰,那么这个警告就有可能出现,与大多数警告不同,如果你在一个循环中,这个警告就会不断重复(python 3.7)。

643ylb08

643ylb086#

我解开了刚才补充的这句话:

ax.set_xticks([1,2,3])
ax.set_xtickslabels(['Label1', 'Label2', 'Label3'])
vu8f3i0k

vu8f3i0k7#

在我的情况下,我使用的是seabornheatmap,这是我如何修复它:
这是抛出警告UserWarning: FixedFormatter should only be used together with FixedLocator cbar.ax.set_yticklabels(cbar.ax.get_yticklabels(), rotation=90, va='center')

heatmap = sb.heatmap(pd.DataFrame(full_dict).T.fillna(0), annot=True, linewidths=1, xticklabels=1, yticklabels=1, annot_kws={'rotation': 90})
cbar = heatmap.collections[0].colorbar
cbar.ax.set_yticklabels(cbar.ax.get_yticklabels(), rotation=90, va='center')

我将其更改为以下内容,以抑制警告:

heatmap = sb.heatmap(pd.DataFrame(full_dict).T.fillna(0), annot=True, linewidths=1, xticklabels=1, yticklabels=1, annot_kws={'rotation': 90})
cbar = heatmap.collections[0].colorbar
cbar.ax.tick_params(axis='y', labelrotation=90)

感谢@Rami的回答:https://stackoverflow.com/a/72099702/264802

qgelzfjb

qgelzfjb8#

只需使用axis.set_xticks([labels])

相关问题