在图例文本中与 Latex 一起使用 matplotlib 散点标记
Using matplotlib scatter markers in text of legend together with Latex
我有一个带插图的情节。后者有一个图例,我想在其文本中使用 matplotlib 散点标记。我还希望能够同时对所有标签和图例使用 LaTeX。我提到这个的原因是因为我看过 this thread 并且那里的解决方案对我不起作用。我会在下面解释为什么。
这是一个示例代码(抱歉我正在绘制的函数,想不出任何东西)
# -*- coding: utf-8 -*-
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid.inset_locator import (inset_axes, InsetPosition, mark_inset)
from matplotlib import rc
rc('text', usetex=True)
N = 50
x = np.random.rand(N)
y = np.random.rand(N)
fig, ax1 = plt.subplots()
ax1.scatter(x, np.cos(x), color = 'blue', marker = "D", s=47.5, label = r'$\cos$')
ax1.scatter(y, np.sin(y), color = 'cyan', marker = "*", alpha = 0.85, label = r'$\sin$')
ax1box = ax1.get_position()
x_value = -0.13
y_value = 0.675
legend=ax1.legend(loc = (ax1box.x0 + x_value, ax1box.y0 + y_value), handletextpad=0.1, prop={'size':8})
frame = legend.get_frame()
frame.set_alpha(0)
frame.set_linewidth(0)
ax2 = plt.axes([0.5,0.5,0.5,0.5])
ip = InsetPosition(ax1, [0.55,0,0.45,0.40])
ax2.set_axes_locator(ip)
ax2.scatter(x, np.tan(x), color = 'gray', marker = "v", s=15, label = r'Insert blue square marker here')
ax2.scatter(y, np.log(y)+1, color = 'brown', marker = "4", s=15, label = r'Insert cyan star marker here')
ax2.xaxis.tick_top()
ax2.xaxis.set_label_position('top')
ax2.yaxis.tick_right()
legend2=ax2.legend(loc = 'lower right', handletextpad=0.1, prop={'size':7})
frame2 = legend2.get_frame()
frame2.set_alpha(0)
frame2.set_linewidth(0)
plt.show()
如果我接受 here 中关于 LaTeX 的建议并尝试
ax2.scatter(x, np.tan(x), color = 'gray', marker = "v", s=15, label = r'$\square$')
图中显示的插图中没有图例。
如果我决定实施 unicode 解决方案
ax2.scatter(x, np.tan(x), color = 'gray', marker = "v", s=15, label = '●')
我收到以下错误
Exception in Tkinter callback
Traceback (most recent call last):
File "/usr/lib/python3.5/tkinter/__init__.py", line 1562, in __call__
return self.func(*args)
File "/usr/local/lib/python3.5/dist-packages/matplotlib/backends/backend_tkagg.py", line 280, in resize
self.show()
File "/usr/local/lib/python3.5/dist-packages/matplotlib/backends/backend_tkagg.py", line 351, in draw
FigureCanvasAgg.draw(self)
File "/usr/local/lib/python3.5/dist-packages/matplotlib/backends/backend_agg.py", line 464, in draw
self.figure.draw(self.renderer)
File "/usr/local/lib/python3.5/dist-packages/matplotlib/artist.py", line 63, in draw_wrapper
draw(artist, renderer, *args, **kwargs)
File "/usr/local/lib/python3.5/dist-packages/matplotlib/figure.py", line 1144, in draw
renderer, self, dsu, self.suppressComposite)
File "/usr/local/lib/python3.5/dist-packages/matplotlib/image.py", line 139, in _draw_list_compositing_images
a.draw(renderer)
File "/usr/local/lib/python3.5/dist-packages/matplotlib/artist.py", line 63, in draw_wrapper
draw(artist, renderer, *args, **kwargs)
File "/usr/local/lib/python3.5/dist-packages/matplotlib/axes/_base.py", line 2426, in draw
mimage._draw_list_compositing_images(renderer, self, dsu)
File "/usr/local/lib/python3.5/dist-packages/matplotlib/image.py", line 139, in _draw_list_compositing_images
a.draw(renderer)
File "/usr/local/lib/python3.5/dist-packages/matplotlib/artist.py", line 63, in draw_wrapper
draw(artist, renderer, *args, **kwargs)
File "/usr/local/lib/python3.5/dist-packages/matplotlib/legend.py", line 471, in draw
bbox = self._legend_box.get_window_extent(renderer)
File "/usr/local/lib/python3.5/dist-packages/matplotlib/offsetbox.py", line 269, in get_window_extent
w, h, xd, yd, offsets = self.get_extent_offsets(renderer)
File "/usr/local/lib/python3.5/dist-packages/matplotlib/offsetbox.py", line 391, in get_extent_offsets
for c in self.get_visible_children()]
File "/usr/local/lib/python3.5/dist-packages/matplotlib/offsetbox.py", line 391, in <listcomp>
for c in self.get_visible_children()]
File "/usr/local/lib/python3.5/dist-packages/matplotlib/offsetbox.py", line 262, in get_extent
w, h, xd, yd, offsets = self.get_extent_offsets(renderer)
File "/usr/local/lib/python3.5/dist-packages/matplotlib/offsetbox.py", line 462, in get_extent_offsets
for c in self.get_visible_children()]
File "/usr/local/lib/python3.5/dist-packages/matplotlib/offsetbox.py", line 462, in <listcomp>
for c in self.get_visible_children()]
File "/usr/local/lib/python3.5/dist-packages/matplotlib/offsetbox.py", line 262, in get_extent
w, h, xd, yd, offsets = self.get_extent_offsets(renderer)
File "/usr/local/lib/python3.5/dist-packages/matplotlib/offsetbox.py", line 391, in get_extent_offsets
for c in self.get_visible_children()]
File "/usr/local/lib/python3.5/dist-packages/matplotlib/offsetbox.py", line 391, in <listcomp>
for c in self.get_visible_children()]
File "/usr/local/lib/python3.5/dist-packages/matplotlib/offsetbox.py", line 262, in get_extent
w, h, xd, yd, offsets = self.get_extent_offsets(renderer)
File "/usr/local/lib/python3.5/dist-packages/matplotlib/offsetbox.py", line 462, in get_extent_offsets
for c in self.get_visible_children()]
File "/usr/local/lib/python3.5/dist-packages/matplotlib/offsetbox.py", line 462, in <listcomp>
for c in self.get_visible_children()]
File "/usr/local/lib/python3.5/dist-packages/matplotlib/offsetbox.py", line 835, in get_extent
bbox, info, d = self._text._get_layout(renderer)
File "/usr/local/lib/python3.5/dist-packages/matplotlib/text.py", line 362, in _get_layout
ismath=ismath)
File "/usr/local/lib/python3.5/dist-packages/matplotlib/backends/backend_agg.py", line 230, in get_text_width_height_descent
renderer=self)
File "/usr/local/lib/python3.5/dist-packages/matplotlib/texmanager.py", line 676, in get_text_width_height_descent
dvifile = self.make_dvi(tex, fontsize)
File "/usr/local/lib/python3.5/dist-packages/matplotlib/texmanager.py", line 399, in make_dvi
texfile = self.make_tex(tex, fontsize)
File "/usr/local/lib/python3.5/dist-packages/matplotlib/texmanager.py", line 314, in make_tex
fh.write(s.encode('ascii'))
UnicodeEncodeError: 'ascii' codec can't encode character '\u25cf' in position 226: ordinal not in range(128)
这似乎是因为我使用的是 LaTeX,就像我注释掉了一样
# from matplotlib import rc
# rc('text', usetex=True)
然后我让一切正常,但没有 LaTeX。 (好吧,我得到的圆圈是黑色的,我还没有研究是否可以改变它的颜色)。不过,我确实想要 LaTeX,所以这对我不利。
正如 The Great, Big List of LaTeX Symbols 告诉我们的,\square
是一个 AMS 符号。所以,为了使用它,你必须把 \usepackage{amssymb}
放在你的序言中,这可以用
rc('text', usetex=True)
rc('text.latex', preamble=r'\usepackage{amssymb}')
我有一个带插图的情节。后者有一个图例,我想在其文本中使用 matplotlib 散点标记。我还希望能够同时对所有标签和图例使用 LaTeX。我提到这个的原因是因为我看过 this thread 并且那里的解决方案对我不起作用。我会在下面解释为什么。
这是一个示例代码(抱歉我正在绘制的函数,想不出任何东西)
# -*- coding: utf-8 -*-
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.axes_grid.inset_locator import (inset_axes, InsetPosition, mark_inset)
from matplotlib import rc
rc('text', usetex=True)
N = 50
x = np.random.rand(N)
y = np.random.rand(N)
fig, ax1 = plt.subplots()
ax1.scatter(x, np.cos(x), color = 'blue', marker = "D", s=47.5, label = r'$\cos$')
ax1.scatter(y, np.sin(y), color = 'cyan', marker = "*", alpha = 0.85, label = r'$\sin$')
ax1box = ax1.get_position()
x_value = -0.13
y_value = 0.675
legend=ax1.legend(loc = (ax1box.x0 + x_value, ax1box.y0 + y_value), handletextpad=0.1, prop={'size':8})
frame = legend.get_frame()
frame.set_alpha(0)
frame.set_linewidth(0)
ax2 = plt.axes([0.5,0.5,0.5,0.5])
ip = InsetPosition(ax1, [0.55,0,0.45,0.40])
ax2.set_axes_locator(ip)
ax2.scatter(x, np.tan(x), color = 'gray', marker = "v", s=15, label = r'Insert blue square marker here')
ax2.scatter(y, np.log(y)+1, color = 'brown', marker = "4", s=15, label = r'Insert cyan star marker here')
ax2.xaxis.tick_top()
ax2.xaxis.set_label_position('top')
ax2.yaxis.tick_right()
legend2=ax2.legend(loc = 'lower right', handletextpad=0.1, prop={'size':7})
frame2 = legend2.get_frame()
frame2.set_alpha(0)
frame2.set_linewidth(0)
plt.show()
如果我接受 here 中关于 LaTeX 的建议并尝试
ax2.scatter(x, np.tan(x), color = 'gray', marker = "v", s=15, label = r'$\square$')
图中显示的插图中没有图例。
如果我决定实施 unicode 解决方案
ax2.scatter(x, np.tan(x), color = 'gray', marker = "v", s=15, label = '●')
我收到以下错误
Exception in Tkinter callback
Traceback (most recent call last):
File "/usr/lib/python3.5/tkinter/__init__.py", line 1562, in __call__
return self.func(*args)
File "/usr/local/lib/python3.5/dist-packages/matplotlib/backends/backend_tkagg.py", line 280, in resize
self.show()
File "/usr/local/lib/python3.5/dist-packages/matplotlib/backends/backend_tkagg.py", line 351, in draw
FigureCanvasAgg.draw(self)
File "/usr/local/lib/python3.5/dist-packages/matplotlib/backends/backend_agg.py", line 464, in draw
self.figure.draw(self.renderer)
File "/usr/local/lib/python3.5/dist-packages/matplotlib/artist.py", line 63, in draw_wrapper
draw(artist, renderer, *args, **kwargs)
File "/usr/local/lib/python3.5/dist-packages/matplotlib/figure.py", line 1144, in draw
renderer, self, dsu, self.suppressComposite)
File "/usr/local/lib/python3.5/dist-packages/matplotlib/image.py", line 139, in _draw_list_compositing_images
a.draw(renderer)
File "/usr/local/lib/python3.5/dist-packages/matplotlib/artist.py", line 63, in draw_wrapper
draw(artist, renderer, *args, **kwargs)
File "/usr/local/lib/python3.5/dist-packages/matplotlib/axes/_base.py", line 2426, in draw
mimage._draw_list_compositing_images(renderer, self, dsu)
File "/usr/local/lib/python3.5/dist-packages/matplotlib/image.py", line 139, in _draw_list_compositing_images
a.draw(renderer)
File "/usr/local/lib/python3.5/dist-packages/matplotlib/artist.py", line 63, in draw_wrapper
draw(artist, renderer, *args, **kwargs)
File "/usr/local/lib/python3.5/dist-packages/matplotlib/legend.py", line 471, in draw
bbox = self._legend_box.get_window_extent(renderer)
File "/usr/local/lib/python3.5/dist-packages/matplotlib/offsetbox.py", line 269, in get_window_extent
w, h, xd, yd, offsets = self.get_extent_offsets(renderer)
File "/usr/local/lib/python3.5/dist-packages/matplotlib/offsetbox.py", line 391, in get_extent_offsets
for c in self.get_visible_children()]
File "/usr/local/lib/python3.5/dist-packages/matplotlib/offsetbox.py", line 391, in <listcomp>
for c in self.get_visible_children()]
File "/usr/local/lib/python3.5/dist-packages/matplotlib/offsetbox.py", line 262, in get_extent
w, h, xd, yd, offsets = self.get_extent_offsets(renderer)
File "/usr/local/lib/python3.5/dist-packages/matplotlib/offsetbox.py", line 462, in get_extent_offsets
for c in self.get_visible_children()]
File "/usr/local/lib/python3.5/dist-packages/matplotlib/offsetbox.py", line 462, in <listcomp>
for c in self.get_visible_children()]
File "/usr/local/lib/python3.5/dist-packages/matplotlib/offsetbox.py", line 262, in get_extent
w, h, xd, yd, offsets = self.get_extent_offsets(renderer)
File "/usr/local/lib/python3.5/dist-packages/matplotlib/offsetbox.py", line 391, in get_extent_offsets
for c in self.get_visible_children()]
File "/usr/local/lib/python3.5/dist-packages/matplotlib/offsetbox.py", line 391, in <listcomp>
for c in self.get_visible_children()]
File "/usr/local/lib/python3.5/dist-packages/matplotlib/offsetbox.py", line 262, in get_extent
w, h, xd, yd, offsets = self.get_extent_offsets(renderer)
File "/usr/local/lib/python3.5/dist-packages/matplotlib/offsetbox.py", line 462, in get_extent_offsets
for c in self.get_visible_children()]
File "/usr/local/lib/python3.5/dist-packages/matplotlib/offsetbox.py", line 462, in <listcomp>
for c in self.get_visible_children()]
File "/usr/local/lib/python3.5/dist-packages/matplotlib/offsetbox.py", line 835, in get_extent
bbox, info, d = self._text._get_layout(renderer)
File "/usr/local/lib/python3.5/dist-packages/matplotlib/text.py", line 362, in _get_layout
ismath=ismath)
File "/usr/local/lib/python3.5/dist-packages/matplotlib/backends/backend_agg.py", line 230, in get_text_width_height_descent
renderer=self)
File "/usr/local/lib/python3.5/dist-packages/matplotlib/texmanager.py", line 676, in get_text_width_height_descent
dvifile = self.make_dvi(tex, fontsize)
File "/usr/local/lib/python3.5/dist-packages/matplotlib/texmanager.py", line 399, in make_dvi
texfile = self.make_tex(tex, fontsize)
File "/usr/local/lib/python3.5/dist-packages/matplotlib/texmanager.py", line 314, in make_tex
fh.write(s.encode('ascii'))
UnicodeEncodeError: 'ascii' codec can't encode character '\u25cf' in position 226: ordinal not in range(128)
这似乎是因为我使用的是 LaTeX,就像我注释掉了一样
# from matplotlib import rc
# rc('text', usetex=True)
然后我让一切正常,但没有 LaTeX。 (好吧,我得到的圆圈是黑色的,我还没有研究是否可以改变它的颜色)。不过,我确实想要 LaTeX,所以这对我不利。
正如 The Great, Big List of LaTeX Symbols 告诉我们的,\square
是一个 AMS 符号。所以,为了使用它,你必须把 \usepackage{amssymb}
放在你的序言中,这可以用
rc('text', usetex=True)
rc('text.latex', preamble=r'\usepackage{amssymb}')