从 matplotlibrc 文件加载 matplotlib rcparams 时,Jupyter 笔记本内联绘图中断

Seb*_*der 3 python plot matplotlib jupyter-notebook

我想编写一个具有从matplotlibrc文件设置默认样式参数的函数的模块。该模块的最小示例style.py

import matplotlib as mpl

def set_default():
    mpl.rc_file('./matplotlibrc')
Run Code Online (Sandbox Code Playgroud)

style.set_default()如果我想在带有内联绘图的 jupyter 笔记本中使用该模块,则当我在之前绘制任何内容之前调用时,不会显示内联绘图。

所以如果我打电话

%matplotlib inline
style.set_default()
plt.plot()
Run Code Online (Sandbox Code Playgroud)

输出是一个空列表,并且没有显示任何图。如果我打电话给例如

plt.plot()
Run Code Online (Sandbox Code Playgroud)

启用内联绘图后和调用该函数之前set_default,两次plot调用的输出都会内联显示。

这种情况甚至会发生,当matplotlibrc当文件为空(如我的最小示例中所示)

有谁理解为什么会发生这种情况,并知道如何解决这个问题或以另一种方式使用文件在模块中设置默认样式matplotlibrc

这也是 Jupyter Notebook 中这两种情况的两张图像:

内联损坏

内联工作

额外问题:当加载的内容是空的时,为什么第二种情况下的第二个图更大matplotlibrc

Imp*_*est 5

简短版本:使用mpl.style.use而不是mpl.rc_file.

长版:
您可以打印出正在使用的后端来看看发生了什么。

import matplotlib as mpl

def set_default():
    mpl.rc_file('matplotlibrc.txt') # this is an empty file

import matplotlib.pyplot as plt
print mpl.get_backend()
# This prints u'TkAgg' (in my case) the default backend in use 
#  due to my rc Params

%matplotlib inline
print mpl.get_backend()
# This prints "module://ipykernel.pylab.backend_inline", because inline has been set
set_default()
print mpl.get_backend()
# This prints "agg", because this is the default backend reset by setting the empty rc file
plt.plot()
# Here, no plot is shown because agg (a non interactive backend) is used.
Run Code Online (Sandbox Code Playgroud)

到这里为止,没有什么惊喜。

现在来说第二种情况。

import matplotlib as mpl

def set_default():
    mpl.rc_file('matplotlibrc.txt') # this is an empty file

import matplotlib.pyplot as plt
print mpl.get_backend()
# This prints u'TkAgg' (in my case) the default backend in use, same as above

%matplotlib inline
print mpl.get_backend()
# This prints "module://ipykernel.pylab.backend_inline", because inline has been set
plt.plot()
# This shows the inline plot, because the inline backend is active.

set_default()
print mpl.get_backend()
# This prints "agg", because this is the default backend reset by setting the new empty rc file
plt.plot()
# Here comes the supprise: Although "agg" is the backend, still, an inline plot is shown.
# This is due to the inline backend being the one registered in pyplot 
#   when doing the first plot. It cannot be changed afterwards.
Run Code Online (Sandbox Code Playgroud)

要点是,您仍然可以更改后端,直到生成第一个图,而不是之后。

同样的论点也适用于图形尺寸。默认的 matplotlib 图形大小是(6.4,4.8),而使用内联后端设置的图形大小是(6.0,4.0)。另外图形dpi也不同,它100在默认的rcParams中,但是72.在内联配置中。这使得情节显得小得多。

现在来解决实际问题。我想这里使用样式表的目的是为绘图设置一些样式,而不是更改后端。因此,您宁愿只从 rc 文件设置样式。这可以通过通常的方式完成,使用matplotlib.style.use

def set_default():
    mpl.style.use('matplotlibrc.txt')
Run Code Online (Sandbox Code Playgroud)

使用此功能时,它不会覆盖正在使用的后端,而只会更新文件本身中指定的那些参数。