【问题标题】:Jupyter notebook inline plotting breaks, when loading matplotlib rcparams from matplotlibrc file从 matplotlibrc 文件加载 matplotlib rcparams 时,Jupyter 笔记本内联绘图中断
【发布时间】:2018-06-27 11:55:08
【问题描述】:

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

import matplotlib as mpl

def set_default():
    mpl.rc_file('./matplotlibrc')

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

所以如果我打电话给

%matplotlib inline
style.set_default()
plt.plot()

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

plt.plot()

在启用内联绘图之后和调用set_default 函数之前,两个plot 调用的输出都以内联方式显示。

matplotlibrc 文件为空时,甚至会发生这种情况,就像在我的最小示例中一样。

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

这也是 jupyter notebook 中这两种情况的两张图片:

inline broken

inline working

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

【问题讨论】:

  • 首先,您可以尝试在笔记本的第一行(在任何导入之前)使用%matplotlib inline 行吗?
  • 试过了,但没有任何改变。

标签: python matplotlib plot jupyter-notebook


【解决方案1】:

短版:使用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.

直到这里没有惊喜。

现在是第二种情况。

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.

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

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

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

def set_default():
    mpl.style.use('matplotlibrc.txt')

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

【讨论】:

  • 非常感谢您的细心解释!使用mpl.style.use 可以完美运行,我想我现在明白发生了什么:)
  • 非常感谢。我开始为此失去理智。在一些 jupyter 笔记本单元格中,我调用了一个更改全局样式的脚本,该脚本本身调用 rcdefaults,如果在绘制图形之前调用它会中断内联绘图。根据我在会话开始时选择的单元格,内联绘图似乎任意失败。
  • @LukeDavis 也是我的问题。虽然我使用了 seaborn 并且绘图有效,但如果您导入 seaborn before (真的)运行 rcdefaults。见鬼
猜你喜欢
  • 1970-01-01
  • 2021-03-22
  • 2016-07-21
  • 2013-10-24
  • 2018-10-10
  • 1970-01-01
  • 2017-08-23
相关资源
最近更新 更多