ubuntu中文字体使用与可视化

其实大家很容易就能发现,在ubuntu中通过matplotlib进行绘图时,经常是无法使用中文字体来绘制的,这里我们通过安装额外的中文字体可以解决这个问题。
首先需要导出windows中的一些中文字体,打包为font.zip文件.
在这里插入图片描述

放到主目录的font.zip中。然后运行这个sh文件:

#!/usr/bin/env bash

set -e  # 遇到错误立即退出

# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# 日志函数
log_info() {
    echo -e "${BLUE}[INFO]${NC} $1"
}

log_success() {
    echo -e "${GREEN}[SUCCESS]${NC} $1"
}

log_warning() {
    echo -e "${YELLOW}[WARNING]${NC} $1"
}

log_error() {
    echo -e "${RED}[ERROR]${NC} $1"
}

# 检查是否为root用户或有sudo权限
check_permissions() {
    log_info "检查用户权限..."
    if [[ $EUID -eq 0 ]]; then
        log_success "当前为root用户"
        SUDO_CMD=""
    elif sudo -n true 2>/dev/null; then
        log_success "当前用户有sudo权限"
        SUDO_CMD="sudo"
    else
        log_error "需要root权限或sudo权限来安装字体文件"
        echo "请使用以下命令之一运行此脚本:"
        echo "  sudo $0"
        echo "  或确保当前用户在sudoers中"
        exit 1
    fi
}

# 添加UTF-8 Locale设置到bashrc
add_locale_to_bashrc() {
    log_info "配置UTF-8 Locale设置..."
    
    local bashrc_file="$HOME/.bashrc"
    local locale_config="
# UTF-8 Locale设置 (自动添加)
export LANG=en_US.UTF-8
export LC_ALL=en_US.UTF-8
export LC_CTYPE=en_US.UTF-8
export PYTHONIOENCODING=utf-8
"
    
    # 检查是否已经存在配置
    if grep -q "UTF-8 Locale设置" "$bashrc_file" 2>/dev/null; then
        log_warning "UTF-8 Locale设置已存在于 $HOME/.bashrc 中"
    else
        echo "$locale_config" >> "$bashrc_file"
        log_success "UTF-8 Locale设置已添加到 $HOME/.bashrc"
    fi
    
    # 立即应用环境变量
    export LANG=en_US.UTF-8
    export LC_ALL=en_US.UTF-8
    export LC_CTYPE=en_US.UTF-8
    export PYTHONIOENCODING=utf-8
    
    log_success "环境变量已在当前会话中生效"
}

# 查找字体文件
find_font_files() {
    log_info "查找字体文件..."
    
    # 可能的字体文件位置
    local font_locations=(
        "$HOME/Fonts.zip"
        "$HOME/font.zip"
        "$HOME/fonts.zip"
        "$HOME/Fonts/"
        "./Fonts.zip"
        "./font.zip"
        "./fonts.zip"
    )
    
    for location in "${font_locations[@]}"; do
        if [[ -f "$location" ]] || [[ -d "$location" ]]; then
            FONT_SOURCE="$location"
            log_success "找到字体文件: $location"
            return 0
        fi
    done
    
    log_error "未找到字体文件,请确保以下位置之一存在字体文件:"
    for location in "${font_locations[@]}"; do
        echo "  - $location"
    done
    return 1
}

# 安装字体文件
install_fonts() {
    log_info "安装字体文件..."
    
    # 创建字体目录
    local font_dir="/usr/share/fonts/truetype/chinese"
    $SUDO_CMD mkdir -p "$font_dir"
    log_success "字体目录已创建: $font_dir"
    
    if [[ -f "$FONT_SOURCE" ]] && [[ "$FONT_SOURCE" == *.zip ]]; then
        # 解压zip文件
        log_info "解压字体文件: $FONT_SOURCE"
        local temp_dir=$(mktemp -d)
        log_info "临时目录: $temp_dir"
        
        if ! unzip -q "$FONT_SOURCE" -d "$temp_dir"; then
            log_error "解压失败: $FONT_SOURCE"
            rm -rf "$temp_dir"
            return 1
        fi
        
        log_success "解压完成,查找字体文件..."
        
        # 复制字体文件
        local font_count=0
        while IFS= read -r -d '' font_file; do
            printf '[INFO] 复制: %s\n' "$(basename "$font_file")" >&2
            $SUDO_CMD cp -- "$font_file" "$font_dir/" && ((font_count++)) || {
                printf '[ERROR] 复制失败: %s\n' "$font_file" >&2
            }
        done < <(find "$temp_dir" -type f \( -iname "*.ttf" -o -iname "*.otf" -o -iname "*.ttc" \) -print0)
        # 清理临时目录
        rm -rf "$temp_dir"
        
        if [[ $font_count -gt 0 ]]; then
            log_success "已安装 $font_count 个字体文件到 $font_dir"
        else
            log_error "未找到任何字体文件"
            return 1
        fi
        
    elif [[ -d "$FONT_SOURCE" ]]; then
        # 直接复制目录中的字体文件
        log_info "复制字体目录: $FONT_SOURCE"
        local font_count=0
        while IFS= read -r -d '' font_file; do
            $SUDO_CMD cp "$font_file" "$font_dir/"
            ((font_count++))
        done < <(find "$FONT_SOURCE" -type f \( -name "*.ttf" -o -name "*.otf" -o -name "*.ttc" \) -print0)
        
        log_success "已安装 $font_count 个字体文件到 $font_dir"
    else
        log_error "不支持的字体文件格式: $FONT_SOURCE"
        return 1
    fi
    
    # 设置字体文件权限
    $SUDO_CMD chmod 644 "$font_dir"/*
    log_success "字体文件权限设置完成"
}

# 刷新字体缓存
refresh_font_cache() {
    log_info "刷新系统字体缓存..."
    
    # 刷新字体缓存
    $SUDO_CMD fc-cache -fv > /dev/null 2>&1
    
    log_success "字体缓存刷新完成"
    
    # 验证字体安装
    log_info "验证中文字体安装..."
    local chinese_fonts=("SimHei" "WenQuanYi" "Heiti" "Microsoft YaHei")
    local found_fonts=0
    
    for font in "${chinese_fonts[@]}"; do
        if fc-list | grep -qi "$font"; then
            log_success "找到字体: $font"
            set +e
            ((found_fonts++))
            set -e
        fi
    done
    
    if [[ $found_fonts -gt 0 ]]; then
        log_success "成功安装 $found_fonts 个中文字体"
    else
        log_warning "未检测到已知的中文字体,但字体可能仍然可用"
    fi
}

# 创建Python配置示例
create_python_example() {
    log_info "创建Python matplotlib中文字体配置示例..."
    
    # local example_file="$HOME/matplotlib_chinese_config.py"
    local example_file="$HOME/matplotlib_chinese_config.py"


    cat > "$example_file" << 'EOF'

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
matplotlib中文字体配置示例
使用方法:在你的Python脚本开头添加以下配置
"""

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

# 方法1: 使用rcParams设置(推荐)
def setup_chinese_fonts_rcparams():
    """
    使用rcParams设置中文字体(推荐方法)
    """
    # 设置中文字体优先级列表
    chinese_fonts = [
        'SimHei',           # 黑体
        'WenQuanYi Micro Hei',  # 文泉驿微米黑
        'Heiti TC',         # 黑体-繁
        'Microsoft YaHei',  # 微软雅黑
        'DejaVu Sans'       # 备用字体
    ]
    
    plt.rcParams['font.sans-serif'] = chinese_fonts
    plt.rcParams['axes.unicode_minus'] = False  # 解决负号显示问题
    
    print("已设置中文字体(rcParams方法)")
    print(f"当前字体设置: {plt.rcParams['font.sans-serif']}")

# 方法2: 使用FontProperties
def setup_chinese_fonts_properties():
    """
    使用FontProperties设置中文字体
    """
    try:
        # 尝试不同的中文字体
        font_names = ['SimHei', 'WenQuanYi Micro Hei', 'Microsoft YaHei']
        
        for font_name in font_names:
            try:
                font_prop = FontProperties(fname=font_name)
                print(f"成功创建字体属性: {font_name}")
                return font_prop
            except:
                continue
        
        # 如果都失败,使用系统默认
        print("使用系统默认字体")
        return FontProperties()
        
    except Exception as e:
        print(f"字体设置失败: {e}")
        return None

# 测试函数
def test_chinese_display():
    """
    测试中文显示效果
    """
    # 设置中文字体
    setup_chinese_fonts_rcparams()
    
    # 创建测试数据
    x = np.linspace(0, 2*np.pi, 100)
    y1 = np.sin(x)
    y2 = np.cos(x)
    
    # 创建图表
    plt.figure(figsize=(10, 6))
    
    # 绘制曲线
    plt.plot(x, y1, label='正弦函数', linewidth=2)
    plt.plot(x, y2, label='余弦函数', linewidth=2)
    
    # 设置标题和标签
    plt.title('中文字体测试 - 三角函数图像', fontsize=16, fontweight='bold')
    plt.xlabel('角度 (弧度)', fontsize=12)
    plt.ylabel('函数值', fontsize=12)
    
    # 添加图例
    plt.legend(fontsize=12)
    
    # 添加网格
    plt.grid(True, alpha=0.3)
    
    # 保存图片
    import os
    output_file = os.path.expanduser('~/chinese_font_test.png')
    plt.savefig(output_file, dpi=300, bbox_inches='tight')
    print(f"测试图片已保存到: {output_file}")
    
    # 显示图片(如果在支持的环境中)
    try:
        plt.show()
    except:
        print("无法显示图片,但已保存到文件")

if __name__ == '__main__':
    print("=== matplotlib中文字体配置测试 ===")
    
    # 显示当前matplotlib配置
    print(f"matplotlib版本: {mpl.__version__}")
    print(f"当前字体设置: {plt.rcParams['font.sans-serif']}")
    
    # 运行测试
    test_chinese_display()
    
    print("\n=== 使用说明 ===")
    print("在你的Python脚本中添加以下代码:")
    print("")
    print("import matplotlib.pyplot as plt")
    print("plt.rcParams['font.sans-serif'] = ['SimHei', 'WenQuanYi Micro Hei', 'Heiti TC']")
    print("plt.rcParams['axes.unicode_minus'] = False")
    print("")
    print("然后就可以正常使用中文标题、标签和图例了!")
EOF

    chmod +x "$example_file"
    log_success "Python配置示例已创建: $example_file"
}

# 生成安装报告
generate_report() {
    log_info "生成安装报告..."
    
    local report_file="$HOME/font_setup_report.txt"
    
    cat > "$report_file" << EOF
中文字体自动配置报告
生成时间: $(date '+%Y-%m-%d %H:%M:%S')

=== 配置摘要 ===
✓ UTF-8 Locale环境变量已设置
✓ 字体文件已安装到系统目录
✓ 字体缓存已刷新
✓ Python配置示例已创建

=== 环境变量设置 ===
LANG=en_US.UTF-8
LC_ALL=en_US.UTF-8
LC_CTYPE=en_US.UTF-8
PYTHONIOENCODING=utf-8

=== 字体安装位置 ===
/usr/share/fonts/truetype/chinese/

=== Python使用方法 ===
在Python脚本中添加以下代码:

import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei', 'WenQuanYi Micro Hei', 'Heiti TC']
plt.rcParams['axes.unicode_minus'] = False

=== 验证方法 ===
1. 重启终端或运行: source $HOME/.bashrc
2. 运行Python测试脚本: python3 $HOME/matplotlib_chinese_config.py
3. 检查生成的测试图片: $HOME/chinese_font_test.png

=== 可用字体列表 ===
EOF

    # 添加系统中的中文字体列表
    fc-list | grep -i -E "(chinese|simhei|yahei|wenquanyi|heiti)" >> "$report_file" 2>/dev/null || echo "未找到已知的中文字体" >> "$report_file"
    
    log_success "安装报告已生成: $report_file"
}

# 主函数
main() {
    echo "==========================================="
    echo "     中文字体自动配置脚本 v1.0"
    echo "==========================================="
    echo
    
    # 检查权限
    check_permissions

    
    # 添加locale设置
    add_locale_to_bashrc
    
    # 查找并安装字体
    if find_font_files; then
        install_fonts
        refresh_font_cache
    else
        log_warning "跳过字体安装步骤"
    fi
    
    # 创建Python配置示例
    create_python_example
    
    # 生成报告
    generate_report
    
    echo
    echo "==========================================="
    log_success "中文字体配置完成!"
    echo "==========================================="
    echo
    echo "下一步操作:"
    echo "1. 重启终端或运行: source $HOME/.bashrc"
    echo "2. 测试Python配置: python3 $HOME/matplotlib_chinese_config.py"
    echo "3. 查看安装报告: cat $HOME/font_setup_report.txt"
    echo
}

# 错误处理
trap 'log_error "脚本执行过程中发生错误,请检查上面的错误信息"' ERR

# 运行主函数
main "$@"

这里面执行了一些创建工作和设置环境工作。然后直接执行:

python3 ~/matplotlib_chinese_config.py

就可以测试是否能够正常使用了
在这里插入图片描述
后续的图如果需要中文字体,设置一下即可:

import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei', 'WenQuanYi Micro Hei', 'Heiti TC']
plt.rcParams['axes.unicode_minus'] = False
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

白云千载尽

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值