无法解释的 Python 错误:RuntimeError: Failed to process string with tex because latex could not be found

问题描述 投票:0回答:0

我正在尝试使用 matplotlib 在绘图中使用 LaTeX 文本制作一个简单的绘图,但我一直遇到同样的错误。我在通过 Anaconda 安装的 Jupyter 笔记本上工作,我的代码如下:

import numpy as np
import matplotlib.pyplot as plt

plt.rcParpythonams.update(plt.rcParamsDefault)
plt.rcParams.update({
    'text.usetex' : True,
    "font.family": "Times New Roman",
    "font.monospace": 'Computer Modern'
})

x = np.linspace(0,5,100)
figure = plt.figure()
plt.xlabel('$x$')
plt.ylabel('$y$')
plt.title('$y=x^2$')
plt.plot(x, x**2)
plt.show()

我知道这是一个双重问题,但我可能已经阅读了所有建议的解决方案,但似乎没有任何效果......

运行上述代码时弹出的错误如下:

---------------------------------------------------------------------------
FileNotFoundError                         Traceback (most recent call last)
File ~\anaconda3\lib\site-packages\matplotlib\texmanager.py:255, in TexManager._run_checked_subprocess(cls, command, tex, cwd)
    254 try:
--> 255     report = subprocess.check_output(
    256         command, cwd=cwd if cwd is not None else cls.texcache,
    257         stderr=subprocess.STDOUT)
    258 except FileNotFoundError as exc:

File ~\anaconda3\lib\subprocess.py:421, in check_output(timeout, *popenargs, **kwargs)
    419     kwargs['input'] = empty
--> 421 return run(*popenargs, stdout=PIPE, timeout=timeout, check=True,
    422            **kwargs).stdout

File ~\anaconda3\lib\subprocess.py:503, in run(input, capture_output, timeout, check, *popenargs, **kwargs)
    501     kwargs['stderr'] = PIPE
--> 503 with Popen(*popenargs, **kwargs) as process:
    504     try:

File ~\anaconda3\lib\subprocess.py:971, in Popen.__init__(self, args, bufsize, executable, stdin, stdout, stderr, preexec_fn, close_fds, shell, cwd, env, universal_newlines, startupinfo, creationflags, restore_signals, start_new_session, pass_fds, user, group, extra_groups, encoding, errors, text, umask, pipesize)
    968             self.stderr = io.TextIOWrapper(self.stderr,
    969                     encoding=encoding, errors=errors)
--> 971     self._execute_child(args, executable, preexec_fn, close_fds,
    972                         pass_fds, cwd, env,
    973                         startupinfo, creationflags, shell,
    974                         p2cread, p2cwrite,
    975                         c2pread, c2pwrite,
    976                         errread, errwrite,
    977                         restore_signals,
    978                         gid, gids, uid, umask,
    979                         start_new_session)
    980 except:
    981     # Cleanup if the child failed starting.

File ~\anaconda3\lib\subprocess.py:1440, in Popen._execute_child(self, args, executable, preexec_fn, close_fds, pass_fds, cwd, env, startupinfo, creationflags, shell, p2cread, p2cwrite, c2pread, c2pwrite, errread, errwrite, unused_restore_signals, unused_gid, unused_gids, unused_uid, unused_umask, unused_start_new_session)
   1439 try:
-> 1440     hp, ht, pid, tid = _winapi.CreateProcess(executable, args,
   1441                              # no special security
   1442                              None, None,
   1443                              int(not close_fds),
   1444                              creationflags,
   1445                              env,
   1446                              cwd,
   1447                              startupinfo)
   1448 finally:
   1449     # Child is launched. Close the parent's copy of those pipe
   1450     # handles that only the child should have open.  You need
   (...)
   1453     # pipe will not close when the child process exits and the
   1454     # ReadFile will hang.

FileNotFoundError: [WinError 2] Het systeem kan het opgegeven bestand niet vinden

The above exception was the direct cause of the following exception:

RuntimeError                              Traceback (most recent call last)
File ~\anaconda3\lib\site-packages\IPython\core\formatters.py:338, in BaseFormatter.__call__(self, obj)
    336     pass
    337 else:
--> 338     return printer(obj)
    339 # Finally look for special method names
    340 method = get_real_method(obj, self.print_method)

File ~\anaconda3\lib\site-packages\IPython\core\pylabtools.py:152, in print_figure(fig, fmt, bbox_inches, base64, **kwargs)
    149     from matplotlib.backend_bases import FigureCanvasBase
    150     FigureCanvasBase(fig)
--> 152 fig.canvas.print_figure(bytes_io, **kw)
    153 data = bytes_io.getvalue()
    154 if fmt == 'svg':

File ~\anaconda3\lib\site-packages\matplotlib\backend_bases.py:2338, in FigureCanvasBase.print_figure(self, filename, dpi, facecolor, edgecolor, orientation, format, bbox_inches, pad_inches, bbox_extra_artists, backend, **kwargs)
   2332     renderer = _get_renderer(
   2333         self.figure,
   2334         functools.partial(
   2335             print_method, orientation=orientation)
   2336     )
   2337     with getattr(renderer, "_draw_disabled", nullcontext)():
-> 2338         self.figure.draw(renderer)
   2340 if bbox_inches:
   2341     if bbox_inches == "tight":

File ~\anaconda3\lib\site-packages\matplotlib\artist.py:95, in _finalize_rasterization.<locals>.draw_wrapper(artist, renderer, *args, **kwargs)
     93 @wraps(draw)
     94 def draw_wrapper(artist, renderer, *args, **kwargs):
---> 95     result = draw(artist, renderer, *args, **kwargs)
     96     if renderer._rasterizing:
     97         renderer.stop_rasterizing()

File ~\anaconda3\lib\site-packages\matplotlib\artist.py:72, in allow_rasterization.<locals>.draw_wrapper(artist, renderer)
     69     if artist.get_agg_filter() is not None:
     70         renderer.start_filter()
---> 72     return draw(artist, renderer)
     73 finally:
     74     if artist.get_agg_filter() is not None:

File ~\anaconda3\lib\site-packages\matplotlib\figure.py:3125, in Figure.draw(self, renderer)
   3122         # ValueError can occur when resizing a window.
   3124 self.patch.draw(renderer)
-> 3125 mimage._draw_list_compositing_images(
   3126     renderer, self, artists, self.suppressComposite)
   3128 for sfig in self.subfigs:
   3129     sfig.draw(renderer)

File ~\anaconda3\lib\site-packages\matplotlib\image.py:131, in _draw_list_compositing_images(renderer, parent, artists, suppress_composite)
    129 if not_composite or not has_images:
    130     for a in artists:
--> 131         a.draw(renderer)
    132 else:
    133     # Composite any adjacent images together
    134     image_group = []

File ~\anaconda3\lib\site-packages\matplotlib\artist.py:72, in allow_rasterization.<locals>.draw_wrapper(artist, renderer)
     69     if artist.get_agg_filter() is not None:
     70         renderer.start_filter()
---> 72     return draw(artist, renderer)
     73 finally:
     74     if artist.get_agg_filter() is not None:

File ~\anaconda3\lib\site-packages\matplotlib\axes\_base.py:3030, in _AxesBase.draw(self, renderer)
   3027     for spine in self.spines.values():
   3028         artists.remove(spine)
-> 3030 self._update_title_position(renderer)
   3032 if not self.axison:
   3033     for _axis in self._axis_map.values():

File ~\anaconda3\lib\site-packages\matplotlib\axes\_base.py:2974, in _AxesBase._update_title_position(self, renderer)
   2972 top = max(top, bb.ymax)
   2973 if title.get_text():
-> 2974     ax.yaxis.get_tightbbox(renderer)  # update offsetText
   2975     if ax.yaxis.offsetText.get_text():
   2976         bb = ax.yaxis.offsetText.get_tightbbox(renderer)

File ~\anaconda3\lib\site-packages\matplotlib\axis.py:1320, in Axis.get_tightbbox(self, renderer, for_layout_only)
   1317     renderer = self.figure._get_renderer()
   1318 ticks_to_draw = self._update_ticks()
-> 1320 self._update_label_position(renderer)
   1322 # go back to just this axis's tick labels
   1323 tlb1, tlb2 = self._get_ticklabel_bboxes(ticks_to_draw, renderer)

File ~\anaconda3\lib\site-packages\matplotlib\axis.py:2569, in YAxis._update_label_position(self, renderer)
   2565     return
   2567 # get bounding boxes for this axis and any siblings
   2568 # that have been set by `fig.align_ylabels()`
-> 2569 bboxes, bboxes2 = self._get_tick_boxes_siblings(renderer=renderer)
   2570 x, y = self.label.get_position()
   2571 if self.label_position == 'left':

File ~\anaconda3\lib\site-packages\matplotlib\axis.py:2104, in Axis._get_tick_boxes_siblings(self, renderer)
   2102 axis = getattr(ax, f"{axis_name}axis")
   2103 ticks_to_draw = axis._update_ticks()
-> 2104 tlb, tlb2 = axis._get_ticklabel_bboxes(ticks_to_draw, renderer)
   2105 bboxes.extend(tlb)
   2106 bboxes2.extend(tlb2)

File ~\anaconda3\lib\site-packages\matplotlib\axis.py:1299, in Axis._get_ticklabel_bboxes(self, ticks, renderer)
   1297 if renderer is None:
   1298     renderer = self.figure._get_renderer()
-> 1299 return ([tick.label1.get_window_extent(renderer)
   1300          for tick in ticks if tick.label1.get_visible()],
   1301         [tick.label2.get_window_extent(renderer)
   1302          for tick in ticks if tick.label2.get_visible()])

File ~\anaconda3\lib\site-packages\matplotlib\axis.py:1299, in <listcomp>(.0)
   1297 if renderer is None:
   1298     renderer = self.figure._get_renderer()
-> 1299 return ([tick.label1.get_window_extent(renderer)
   1300          for tick in ticks if tick.label1.get_visible()],
   1301         [tick.label2.get_window_extent(renderer)
   1302          for tick in ticks if tick.label2.get_visible()])

File ~\anaconda3\lib\site-packages\matplotlib\text.py:959, in Text.get_window_extent(self, renderer, dpi)
    954     raise RuntimeError(
    955         "Cannot get window extent of text w/o renderer. You likely "
    956         "want to call 'figure.draw_without_rendering()' first.")
    958 with cbook._setattr_cm(self.figure, dpi=dpi):
--> 959     bbox, info, descent = self._get_layout(self._renderer)
    960     x, y = self.get_unitless_position()
    961     x, y = self.get_transform().transform((x, y))

File ~\anaconda3\lib\site-packages\matplotlib\text.py:378, in Text._get_layout(self, renderer)
    375 ys = []
    377 # Full vertical extent of font, including ascenders and descenders:
--> 378 _, lp_h, lp_d = _get_text_metrics_with_cache(
    379     renderer, "lp", self._fontproperties,
    380     ismath="TeX" if self.get_usetex() else False, dpi=self.figure.dpi)
    381 min_dy = (lp_h - lp_d) * self._linespacing
    383 for i, line in enumerate(lines):

File ~\anaconda3\lib\site-packages\matplotlib\text.py:97, in _get_text_metrics_with_cache(renderer, text, fontprop, ismath, dpi)
     94 """Call ``renderer.get_text_width_height_descent``, caching the results."""
     95 # Cached based on a copy of fontprop so that later in-place mutations of
     96 # the passed-in argument do not mess up the cache.
---> 97 return _get_text_metrics_with_cache_impl(
     98     weakref.ref(renderer), text, fontprop.copy(), ismath, dpi)

File ~\anaconda3\lib\site-packages\matplotlib\text.py:105, in _get_text_metrics_with_cache_impl(renderer_ref, text, fontprop, ismath, dpi)
    101 @functools.lru_cache(4096)
    102 def _get_text_metrics_with_cache_impl(
    103         renderer_ref, text, fontprop, ismath, dpi):
    104     # dpi is unused, but participates in cache invalidation (via the renderer).
--> 105     return renderer_ref().get_text_width_height_descent(text, fontprop, ismath)

File ~\anaconda3\lib\site-packages\matplotlib\backends\backend_agg.py:226, in RendererAgg.get_text_width_height_descent(self, s, prop, ismath)
    224 _api.check_in_list(["TeX", True, False], ismath=ismath)
    225 if ismath == "TeX":
--> 226     return super().get_text_width_height_descent(s, prop, ismath)
    228 if ismath:
    229     ox, oy, width, height, descent, font_image = \
    230         self.mathtext_parser.parse(s, self.dpi, prop)

File ~\anaconda3\lib\site-packages\matplotlib\backend_bases.py:641, in RendererBase.get_text_width_height_descent(self, s, prop, ismath)
    637 fontsize = prop.get_size_in_points()
    639 if ismath == 'TeX':
    640     # todo: handle properties
--> 641     return self.get_texmanager().get_text_width_height_descent(
    642         s, fontsize, renderer=self)
    644 dpi = self.points_to_pixels(72)
    645 if ismath:

File ~\anaconda3\lib\site-packages\matplotlib\texmanager.py:368, in TexManager.get_text_width_height_descent(cls, tex, fontsize, renderer)
    366 if tex.strip() == '':
    367     return 0, 0, 0
--> 368 dvifile = cls.make_dvi(tex, fontsize)
    369 dpi_fraction = renderer.points_to_pixels(1.) if renderer else 1
    370 with dviread.Dvi(dvifile, 72 * dpi_fraction) as dvi:

File ~\anaconda3\lib\site-packages\matplotlib\texmanager.py:300, in TexManager.make_dvi(cls, tex, fontsize)
    298     with TemporaryDirectory(dir=cwd) as tmpdir:
    299         tmppath = Path(tmpdir)
--> 300         cls._run_checked_subprocess(
    301             ["latex", "-interaction=nonstopmode", "--halt-on-error",
    302              f"--output-directory={tmppath.name}",
    303              f"{texfile.name}"], tex, cwd=cwd)
    304         (tmppath / Path(dvifile).name).replace(dvifile)
    305 return dvifile

File ~\anaconda3\lib\site-packages\matplotlib\texmanager.py:259, in TexManager._run_checked_subprocess(cls, command, tex, cwd)
    255     report = subprocess.check_output(
    256         command, cwd=cwd if cwd is not None else cls.texcache,
    257         stderr=subprocess.STDOUT)
    258 except FileNotFoundError as exc:
--> 259     raise RuntimeError(
    260         'Failed to process string with tex because {} could not be '
    261         'found'.format(command[0])) from exc
    262 except subprocess.CalledProcessError as exc:
    263     raise RuntimeError(
    264         '{prog} was not able to process the following string:\n'
    265         '{tex!r}\n\n'
   (...)
    272             exc=exc.output.decode('utf-8', 'backslashreplace'))
    273         ) from None

RuntimeError: Failed to process string with tex because latex could not be found

欢迎任何帮助!

我在 Windows 11 上工作并安装了最新版本的 Miktex(我的 LaTeX 解释器中的所有内容都运行良好)。我还在我的系统路径中添加了 Miktex 的正确目录,以便 python 可以找到它。

同样奇怪的是,当通过终端(我的系统命令提示符或 anaconda 命令提示符)访问 python 时,上面的代码工作正常。只有当尝试运行代码是 Jupyter Notebooks 或 VS Code 时,我才会不断收到上述错误。

python matplotlib latex anaconda3 miktex
© www.soinside.com 2019 - 2024. All rights reserved.