【python】Matplotlib+LaTeX绘图 & 字符加粗 || 代码合集

【start:240814】

动机

在使用Python的Matplotlib库绘图时,在非LaTeX模式下,似乎无法同时对LaTeX变量进行“加粗、加斜体”的操作,于是计划转向使用LaTeX模式。

Matplotlib库

调用

import matplotlib as mpl  
import matplotlib.pyplot as plt
from matplotlib.font_manager import FontProperties

报错

这时,如果没有提前安装latex软件,而直接运行

mpl.rcParams['text.usetex'] = True

会报错:

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

这说明我们还没有安装好latex软件,需要先安装再使用

LaTeX 模式

安装

先下载、安装latex软件

【ref】LaTex安装及使用(一)

然后,在python环境中安装latex库

pip install latex

使用

import matplotlib as mpl  
import matplotlib.pyplot as plt
from matplotlib.font_manager import FontProperties

mpl.rcParams['text.usetex'] = True
mpl.rcParams['text.latex.preamble'] = r"""
\usepackage{textcomp}
\usepackage{amsmath}
"""

其中:

mpl.rc('text', usetex=True):这行代码将 Matplotlib 配置为使用 LaTeX 引擎来渲染文本。这使得你可以使用 LaTeX 语法来定义文本的样式和格式。LaTeX 是一个强大的排版系统,特别适合处理复杂的数学公式和符号。

mpl.rcParams['text.latex.preamble']=[r"\usepackage{...}"]:这行代码指定了一个 LaTeX 的前导部分,用于加载额外的 LaTeX 包。在这个例子中,加载了 amsmath 包,它提供了许多增强的数学功能,如更多的数学符号和公式格式选项。

配置属性:text.latex.preamble

属性简介

text.latex.preamble 中,你可以添加许多 LaTeX 包来扩展 Matplotlib 渲染 LaTeX 文本的功能。以下是一些常用的 LaTeX 包及其功能:

  1. amsmath: 提供增强的数学公式支持和环境,例如对齐、分数和矩阵。

    \usepackage{amsmath}
    
  2. amssymb: 提供额外的数学符号,例如黑板粗体字母和额外的符号。

    \usepackage{amssymb}
    
  3. amsfonts: 提供额外的数学字体,例如黑板粗体字母和其他特殊符号。

    \usepackage{amsfonts}
    
  4. mathrsfs: 提供花体数学字体,用于书写特殊的数学符号。

    \usepackage{mathrsfs}
    
  5. siunitx: 用于处理和格式化单位和数值数据。

    \usepackage{siunitx}
    
  6. xcolor: 提供颜色支持,可以为文本和图形添加颜色。

    \usepackage{xcolor}
    
  7. geometry: 控制页面布局和边距设置。

    \usepackage{geometry}
    
  8. graphicx: 提供图像处理功能,例如缩放、旋转图像。

    \usepackage{graphicx}
    
  9. tikz: 提供用于创建图形和图表的强大工具。

    \usepackage{tikz}
    
  10. babel: 提供多语言支持,根据所选语言调整排版规则。

    \usepackage[english]{babel}
    

这些包可以通过在 text.latex.preamble 中添加相关的 \usepackage 命令来加载。例如:

import matplotlib.pyplot as plt
import matplotlib as mpl

mpl.rcParams['text.usetex'] = True
mpl.rcParams['text.latex.preamble'] = r"""
\usepackage{amsmath}
\usepackage{amssymb}
\usepackage{xcolor}
"""

你可以根据需要选择并组合这些包,以满足特定的排版和渲染需求。

amsmath

可以搭配:
\boldsymbol{}:斜体,加粗希腊字符和文本

textcomp

可以使用:
\textmu

非LaTeX 模式

配置属性:mpl.rcParams[‘…’]

mpl.rcParams['font.family'] = 'serif'
mpl.rcParams['font.serif'] = ['Times New Roman']
mpl.rcParams['font.weight'] = 'bold'
mpl.rcParams['xtick.labelsize'] = 20
mpl.rcParams['ytick.labelsize'] = 20

mpl.rcParams[‘font.family’] = ‘serif’:确保字体是衬线字体,有时加粗效果会更明显

字符加粗(label)

非LaTeX模式(关闭text.usetex)

函数

用到的函数:
\textbf{}
\textnormal {}
\text{}

\bm{}

案例

在非LaTeX模式下,可以设置全局加粗,但是只能加粗“钱字号外、表示单位”的普通字符,无法加粗“钱字号内的、表示变量”的latex字符

效果:

在这里插入图片描述

代码:

import matplotlib as mpl  
import matplotlib.pyplot as plt
from matplotlib.font_manager import FontProperties

# 设置全局字体属性
plt.rcParams['font.family'] = 'serif'
plt.rcParams['font.serif'] = ['Times New Roman']
plt.rcParams['mathtext.fontset'] = 'stix'
plt.rcParams['mathtext.rm'] = 'Times New Roman'
plt.rcParams['axes.unicode_minus'] = False

label_font = FontProperties(family='serif', weight='bold', size=30)
label_font.set_name('Times New Roman')
tick_font = FontProperties(family='serif', weight='bold', size=20)
tick_font.set_name('Times New Roman')
legend_font = FontProperties(family='serif', weight='bold', size=15)
legend_font.set_name('Times New Roman')

# 创建一些数据进行绘图
x = [1, 2, 3, 4]
y = [10, 20, 25, 30]

# 绘制图形
plt.plot(x, y, marker='o', ms=10, mew=2, mec='blue', mfc='blue', linestyle='--', color='green')

# 设置坐标轴刻度标签的字体
ax = plt.gca()
for label in ax.get_xticklabels() + ax.get_yticklabels():
    label.set_fontproperties(tick_font)  # 设置刻度标签字体属性

# 设置坐标轴的标签和标题
plt.xlabel(r'$d$($\mathbf{\mu}$m)', fontproperties=label_font)
plt.ylabel(r'$J_{net}$(Acm$^{-2}$)', fontproperties=label_font)

# 设置图例字体
plt.legend(['Test Data'], prop=legend_font)

# 显示图形
plt.show()

LaTeX模式(开启text.usetex)

函数

用到的函数:
\boldsymbol{}:斜体,加粗希腊字符和文本
\mathbf{}:斜体,加粗文本
\mathrm{}:斜体,新罗马字体,不加粗文本
\mathdefault{},斜体,不加粗文本
\mathit{},不协体

案例

在LaTeX模式下,latex字符默认斜体,但需要手动加粗

在科研绘图时,变量中的字符应该是斜体的,latex字符加粗用\boldsymbol{},普通text加粗用\mathbf{}

而单位中的字符应该是非斜体的,为了取消latex字符的斜体,可以使用文本类latex字符:\textxx(如\textmu

效果:

在这里插入图片描述

代码:

from matplotlib.ticker import LogFormatterMathtext, ScalarFormatter
class BoldLogFormatter_Log(LogFormatterMathtext):
      def __call__(self, x: float, pos: int = ...):
            return super().__call__(x, pos).replace('mathdefault', 'mathbf') 
class BoldLogFormatter_Sca(ScalarFormatter):
      def __call__(self, x: float, pos: int = ...):
            return super().__call__(x, pos).replace('mathdefault', 'mathbf') 

import re
def format_label(text):
    def format_inner(match):
        return r'$\boldsymbol{' + match.group(1) + r'}$'

    # 检查是否有 $...$ 的部分
    text = re.sub(r'\$([^\$]+)\$', format_inner, text)
    
    # 对剩余的文本进行 \textbf{} 包裹
    # 需要处理特殊情况,比如 $...$ 中已经包含 \textbf{} 的文本
    parts = re.split(r'(\$[^\$]+\$)', text)
    formatted_text = ''
    
    for part in parts:
        if part.startswith('$') and part.endswith('$'):
            formatted_text += part  # 保持 $...$ 不变
        else:
            formatted_text += r'\textbf{' + part + '}'
    
    return formatted_text
import matplotlib.pyplot as plt
from matplotlib.font_manager import FontProperties
import matplotlib as mpl

mpl.rcParams['text.usetex'] = True
mpl.rcParams['text.latex.preamble'] = r"""
\usepackage{textcomp}
\usepackage{amsmath}
"""

mpl.rcParams['font.family'] = 'serif'
mpl.rcParams['font.serif'] = ['Times New Roman']
mpl.rcParams['font.weight'] = 'bold'
plt.rcParams['xtick.labelsize'] = 20
plt.rcParams['ytick.labelsize'] = 20

# 定义字体属性
label_font = FontProperties(family='serif', weight='bold', size=30)
label_font.set_name('Times New Roman')
legend_font = FontProperties(family='serif', weight='bold', size=15)
legend_font.set_name('Times New Roman')

# 创建图形和坐标轴
fig, ax = plt.subplots(figsize=(8,6))

# 创建一些数据进行绘图
x = [1, 2, 3, 4, 5, 6]
y = [1e1, 2e2, 3e3, 4e4, 5e5, 6e6]

# 绘制图形
ax.plot(x, y, marker='o', ms=10, mew=2, mec='blue', mfc='blue', linestyle='--', color='green')

# 添加辅助虚线
# ax.axvline(x=1, color='gray', linestyle='--')
# ax.axhline(y=1, color='gray', linestyle='--')

# 设置坐标轴的标签和标题
ax.set_xlabel(r'$\boldsymbol{d} \textbf{(\textmu m)}$', fontproperties=label_font)
ax.set_ylabel(r'$\boldsymbol{J_{net}} \textbf{(Acm}^\mathbf{{-2}}\textbf{)}$', fontproperties=label_font)

# 设置图例
legend_text = 'Test Data; $T_C$=500K'
ax.legend(labels=[format_label(legend_text)], prop=legend_font, loc='upper left', bbox_to_anchor=(0.05, 0.95))
# legend = ax.legend(prop=legend_font) 
# labels = [text.get_text() for text in legend.get_texts()]
# ax.legend(labels=[format_label(label) for label in labels], prop=legend_font, frameon=False)

# 设置刻度
ax.set_yscale('log')
ax.get_xaxis().set_major_formatter(BoldLogFormatter_Sca())
ax.get_yaxis().set_major_formatter(BoldLogFormatter_Log())
# ax.set_xticks(ax.get_xticks(), [tick._text.replace('mathdefault', 'mathbf') for tick in ax.get_xticklabels()])
# ax.set_yticks(ax.get_yticks(), [tick._text.replace('mathdefault', 'mathbf') for tick in ax.get_yticklabels()])
# print(ax.get_yticks())

# 显示图形
plt.show()

补充材料

字符的基础知识

在使用latex前,还需要先了解一些字符的基础知识

Unicode字符

  • 定义: Unicode是一个字符编码标准,为几乎所有的书写系统中的字符分配唯一的代码点

  • 'μ': 在Python中,Unicode字符可以直接插入字符串中。例如,'μ' 是直接表示希腊字母μ的Unicode字符。

  • \u03bc: 这种表示方式也可以用于表示 Unicode 字符。\u 后跟四个十六进制数字表示一个 Unicode 字符。

  • Python中的使用: Python 3中的字符串默认是Unicode编码,可以直接操作和处理Unicode字符。

greek_letter = 'μ'
print(greek_letter)  # 输出: μ

LaTeX字符

  • 定义: LaTeX是一个排版系统,提供了命令来生成字符和符号。例如,\mu 在LaTeX中表示希腊字母μ。
  • Python中的使用: LaTeX字符通常不是直接在Python中使用的。它们主要用于生成LaTeX文档和数学公式。如果要在Python中使用LaTeX字符,通常是通过绘图库(如Matplotlib)来显示LaTeX格式的文本。
import matplotlib.pyplot as plt

plt.text(0.5, 0.5, r'$\mu$', fontsize=50)
plt.show()

注意:在latex模式下,\textmu这种字符在搭配\mathbf{}时是显示不出来的,需要搭配\textbf{}才能显示出来

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值