直接点运行后matplotlib报错,但在终端python3运行正常

问题经过

问题是在Ubuntu重装了一下之后,之前的代码运行开始报错了;

大致分析一下报错信息,是关于matplotlib的;

Traceback (most recent call last):
  File "/home/hazyparker/projects/RL-notebook/book_examples/Chapter2-MAB1.py", line 137, in 
    plot_results([epsilon_greedy_solver], ["EpsilonGreedy"])
  File "/home/hazyparker/projects/RL-notebook/book_examples/Chapter2-MAB1.py", line 114, in plot_results
    plt.plot(time_list, solver.regrets, label=solver_names[idx])
  File "/home/hazyparker/.local/lib/python3.8/site-packages/matplotlib/pyplot.py", line 2728, in plot
    return gca().plot(
  File "/home/hazyparker/.local/lib/python3.8/site-packages/matplotlib/pyplot.py", line 2225, in gca
    return gcf().gca()
  File "/home/hazyparker/.local/lib/python3.8/site-packages/matplotlib/pyplot.py", line 830, in gcf
    return figure()
  File "/home/hazyparker/.local/lib/python3.8/site-packages/matplotlib/_api/deprecation.py", line 454, in wrapper
    return func(*args, **kwargs)
  File "/home/hazyparker/.local/lib/python3.8/site-packages/matplotlib/pyplot.py", line 771, in figure
    manager = new_figure_manager(
  File "/home/hazyparker/.local/lib/python3.8/site-packages/matplotlib/pyplot.py", line 346, in new_figure_manager
    _warn_if_gui_out_of_main_thread()
  File "/home/hazyparker/.local/lib/python3.8/site-packages/matplotlib/pyplot.py", line 336, in _warn_if_gui_out_of_main_thread
    if (_get_required_interactive_framework(_get_backend_mod()) and
  File "/home/hazyparker/.local/lib/python3.8/site-packages/matplotlib/pyplot.py", line 206, in _get_backend_mod
    switch_backend(dict.__getitem__(rcParams, "backend"))
  File "/home/hazyparker/.local/lib/python3.8/site-packages/matplotlib/pyplot.py", line 266, in switch_backend
    canvas_class = backend_mod.FigureCanvas
AttributeError: module 'backend_interagg' has no attribute 'FigureCanvas'

总结就是,AttributeError: module 'backend_interagg' has no attribute 'FigureCanvas'

这个是个matplotlib的错,有的方法是加上matplotlib.use('TkAgg'),但也没用

可以运行的情况

直接python 路径+文件.py就正常运行,所以这到底是为啥?

源代码
# to realize MAB problem
# use Epsilon Greedy algorithm

# import libs
import numpy as np
import matplotlib.pylab as plt


# class to compose a Bernouli Bandit model, create bandit
class BernoulliBandit:
    # init function
    def __init__(self, K):
        # K numbers to stand the possibility for each trail(K times) 
        self.probs = np.random.uniform(size = K)

        # get the id number of the max possibility
        self.best_id  = np.argmax(self.probs)
        # get the max possibility
        self.max_prob = self.probs[self.best_id]

        # get param K to the class
        self.K = K

    # function for each trail's final
    def step(self, k):
        if np.random.rand() < self.probs[k]:
            # cautions, this should be less equal than probs[k]
            return 1  # trail is a success
        else:
            return 0  # trail is a failure


# class to solver the Bernouli Bandit problem
# created bandit solver
class SolverBandit:
    # init function
    def __init__(self, bandit):
        # get bandit instance from BernouliBandit
        self.bandit = bandit
        # set conut for each bandit's trial
        self.counts = np.zeros(self.bandit.K)
        # set regret for current step
        self.regret = 0
        # set a list to load regrets
        self.regrets = []
        # set a list to load actions
        self.actions = []

    # calculate cumulatice regret
    def update_regret(self, k):
        # update regret by the formula R(a) = Q* - Q(a)
        self.regret = self.regret + self.bandit.max_prob - self.bandit.probs[k]
        self.regrets.append(self.regret) # add it to the regrets list

    # define for override
    def run_one_step(self):
        # In user defined base classes, abstract methods should raise this 
        # exception when they require derived classes to override the method, 
        # or while the class is being developed to indicate that the real 
        # implementation still needs to be added.
        raise NotImplementedError

    
    # main iteration process
    def run(self, num_steps):
        # num_steps means the iteration times
        for _ in range (num_steps):
            k = self.run_one_step()
            self.counts[k] += 1
            self.actions.append(k)
            self.update_regret(k)


# define class for greedy algrothim, inherit from class SolverBandit
class EpsilonGreedy(SolverBandit):
    # init function
    def __init__(self, bandit, epsilon = 0.01, init_prob = 1.0):
        # inherit from it's parent class
        # there a good example telling about super()
        # https://www.runoob.com/python/python-func-super.html
        super().__init__(bandit)
        self.epsilon = epsilon
        # setting all options's prob as value of init_prob
        self.estimates = np.array([init_prob] * self.bandit.K)

    # epsilon greedy algorithm's main process 
    # be advised here, function with the same name of function in 
    # class SolverBandit
    def run_one_step(self):
        # the algorithm formula
        if np.random.random() < self.epsilon:
            # choose one number randomly form 0 to K
            k = np.random.randint(0, self.bandit.K)
        else:
            # choose the max prob from estimated probs
            k = np.argmax(self.estimates)

        # update the estimates array
        r = self.bandit.step(k)  # acquire the final
        self.estimates[k] += 1.0 / (self.counts[k] + 1) * (
            r - self.estimates[k])  # use 1.0 to keep float

        # why return k?
        return k


# define plot function
def plot_results(solvers, solver_names):
    # the use of enumerate can be referred here:
    # https://www.geeksforgeeks.org/enumerate-in-python/
    # this is set for different epsilons' situtions
    for idx, solver in enumerate(solvers):
        time_list = range(len(solver.regrets))
        plt.plot(time_list, solver.regrets, label=solver_names[idx])
    
    plt.xlabel('Time steps')
    plt.ylabel('Cumulative regrets')
    plt.title('%d-armed bandit' % solvers[0].bandit.K)
    plt.legend()
    plt.show()

np.random.seed(1)  # make random numbers be the same

# set 10 arms for Bernouli Bandit
K = 10
bandit_10_arm = BernoulliBandit(K)
print("create %d arms Bernouli Bandit" % K)
print("the max probility is No. %d, with %.4f" %
      (bandit_10_arm.best_id, bandit_10_arm.max_prob))

np.random.seed(1)  # make random numbers be the same
# create greedy solver instance
epsilon_greedy_solver = EpsilonGreedy(bandit_10_arm, epsilon=0.01)
epsilon_greedy_solver.run(5000)
print('epsilon-greedy cumulative regret:', 
    epsilon_greedy_solver.regret)
plot_results([epsilon_greedy_solver], ["EpsilonGreedy"])

我只能说csdn的环境真的一言难尽,https://youtrack.jetbrains.com/issue/PY-56370/No-plots-with-Matplotlib-360-AttributeError-module-backendinteragg-has-no-attribute-FigureCanvas-Did-you-mean-FigureCanvasAgg%EF%BC%8Cmatplotlib%E6%9B%B4%E6%96%B0%E5%90%8E%E5%AF%B9%E4%BA%8Epycharm%E7%9A%84%E4%B8%93%E5%B1%9Ebug%EF%BC%8C%E6%8C%89%E6%AD%A5%E9%AA%A4%E6%93%8D%E4%BD%9C%E5%B0%B1%E5%8F%AF%E4%BB%A5%E9%81%BF%E5%85%8D%EF%BC%8C%E9%A2%84%E8%AE%A1%E4%BC%9A%E5%9C%A8%E4%B8%8B%E6%AC%A1%E6%9B%B4%E6%96%B0%E4%B8%AD%E4%BF%AE%E5%A4%8D%EF%BC%9B%E8%AF%84%E8%AE%BA%E4%B8%80%E7%9B%B4%E5%86%8D%E8%AF%B4python3%E7%8E%AF%E5%A2%83%E7%9A%84%E9%97%AE%E9%A2%98%EF%BC%8C%E6%8B%BF%E7%BB%88%E7%AB%AF%E7%9B%B4%E6%8E%A5%E8%B7%91%E5%87%BA%E6%9D%A5%E6%AD%A3%E5%B8%B8%E7%BB%93%E6%9E%9C%E6%80%8E%E4%B9%88%E5%8F%AF%E8%83%BD%E6%98%AF%E7%8E%AF%E5%A2%83%E9%97%AE%E9%A2%98%E3%80%82

这个好说,先把代码拿到Windows环境,运行一哈,看看有什么问题,如果可运行,说明你的Ubuntu环境给整劈叉了,原来怎么配的在来一次就可以了。然后,pycharm安装一个,然后用pycharm打断点,仔细查看代码逻辑这些的,看是从哪开始报错的就行了啊。具体如何打断点,百度即可,没什么难度的。

两个pyuthon解释器不一样,导致环境不一样,所以会有差异