Python绘图如何显示中文标题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python绘图如何显示中文标题相关的知识,希望对你有一定的参考价值。

采用matplotlib作图时默认设置下是无法显示中文的,例如编写如下python脚本,
#-*- coding: utf-8 -*-
from pylab import *
t = arange(-4*pi, 4*pi, 0.01)
y = sin(t)/t
plt.plot(t, y)
plt.title(u'钟形函数')
plt.xlabel(u'时间')
plt.ylabel(u'幅度')
plt.show()
显示出来的结果如图1所示,可见标题、标签都无法正常显示中文:
图1
实际上,matplotlib是支持unicode编码的,出现图1的问题主要是没有找到合适的中文字体,在matplotlib的配置文件中,可以看到字体的默认设置如下:
#font.family : sans-serif
#font.sans-serif : Bitstream Vera Sans, Lucida Grande, Verdana, Geneva, Lucid, Arial, Helvetica, Avant Garde, sans-serif
并没有中文字体,所以我们只要手动添加中文字体的名称就可以了,不过并不是添加我们熟悉的“宋体”或“黑体”这类的名称,而是要添加字体管理器识别出的字体名称,matplotlib自身实现的字体管理器在文件font_manager.py中,自动生成的可用字体信息在保存在文件fontList.cache里,可以搜索这个文件查看对应字体的名称,例如simhei.ttf对应的名称为’SimHei’,simkai.ttf对应的名称为’KaiTi_GB2312’等。因此我们只要把这些名称添加到配置文件中去就可以让matplotlib显示中文,修改的方法有两种:
1. 直接修改配置文件matplotlibrc
在配置文件中找到font.sans-serif的设置,然后添加需要的中文字体名称,例如:
font.sans-serif : SimHei, Bitstream Vera Sans, Lucida Grande, Verdana, Geneva, Lucid, Arial, Helvetica, Avant Garde, sans-serif
2. 动态设置(推荐方式)
在python脚本中动态设置matplotlibrc,这样不需要更改配置文件,方便灵活,例如:
mpl.rcParams['font.sans-serif'] = ['SimHei']
修改后的代码如下:
#-*- coding: utf-8 -*-
from pylab import *
mpl.rcParams['font.sans-serif'] = ['SimHei']
t = arange(-4*pi, 4*pi, 0.01)
y = sin(t)/t
plt.plot(t, y)
plt.title(u'钟形函数')
plt.xlabel(u'时间')
plt.ylabel(u'幅度')
plt.show()
显示出来的结果如图2所示,可见标题、标签都能正常显示中文:
图2
但是细心些可以看出图2显示的结果并不正确,注意对比图1和图2的横坐标的坐标值,会发现图2中负轴的横坐标值不对,负号不见了!很明显,这不是程序的错误,而是由于更改了字体导致显示不出负号,在配置文件中我们可以在axes相关设置里找到如下设置:
#axes.unicode_minus : True
可见默认情况下采用的是unicode的minus,看来我们选择的字体对这点支持不够,所以只要把它设置为False就可以了,最终的代码如下:
#-*- coding: utf-8 -*-
from pylab import *
mpl.rcParams['font.sans-serif'] = ['SimHei']
mpl.rcParams['axes.unicode_minus'] = False
t = arange(-4*pi, 4*pi, 0.01)
y = sin(t)/t
plt.plot(t, y)
plt.title(u'钟形函数')
plt.xlabel(u'时间')
plt.ylabel(u'幅度')
plt.show()
最终显示的结果如图3所示,一切都正常了。
参考技术A 代码添加如下就可以了
from pylab import *

# 解决坐标轴负刻度乱码问题
rcParams['axes.unicode_minus'] = False
# 解决中文乱码问题
rcParams['font.sans-serif'] = ['Simhei']

在 Python 中的 Tkinter 主窗口上放置绘图

【中文标题】在 Python 中的 Tkinter 主窗口上放置绘图【英文标题】:Placing plot on Tkinter main window in Python 【发布时间】:2015-10-05 01:41:00 【问题描述】:

我有一个程序可以处理数据然后绘制结果。通常在 Python 中,绘图显示在新窗口中,但我想在同一个 Tkinter 窗口中显示绘图。我搜索并找到了这两个答案,Python Tkinter Embed Matplotlib in GUI 和How do I refresh a matplotlib plot in a Tkinter window?。他们说我们应该首先制作一个画布,然后使用网格或包将其放置在窗口上。这是我第一次使用画布,我已经应用了这个概念,这里有一个工作示例代码,

from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg

__author__ = 'Dania'
import numpy as np
from Tkinter import *
import matplotlib.pyplot as plt
class mclass:
    def __init__(self,  window):
        self.box = Entry(window)
        self.button = Button (window, text="check", command=self.plot)
        self.box.pack ()
        self.button.pack()

    def plot (self):
        x=np.array ([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
        v= np.array ([16,16.31925,17.6394,16.003,17.2861,17.3131,19.1259,18.9694,22.0003,22.81226])
        p= np.array ([16.23697,     17.31653,     17.22094,     17.68631,     17.73641 ,    18.6368,
            19.32125,     19.31756 ,    21.20247  ,   22.41444   ,  22.11718  ,   22.12453])

        plt.scatter(v,x,color='red')
        plt.plot(p, range(2 +max(x)),color='blue')
        plt.gca().invert_yaxis()

        plt.suptitle ("Estimation Grid", fontsize=16)
        plt.ylabel("Y", fontsize=14)
        plt.xlabel("X", fontsize=14)
        plt.show()
        plt.gcf().canvas.draw()
        fig = plt.figure()
        canvas = FigureCanvasTkAgg(fig, master=window)
        canvas.get_tk_widget().grid(row=1,column=24)
        canvas.draw()

window= Tk()
start= mclass (window)
window.mainloop()

上面的代码首先在单独的窗口中显示绘图,然后在网格中指定的位置显示没有绘图的灰色画布。此外,画布垂直扩展并且窗口的一部分消失,换句话说,画布将其下方的内容向下推,并且它们不再出现,因为没有出现垂直滚动条。

我想在同一个 Tkinter 窗口中显示绘图,如果有任何内容被按下,我希望能够滚动窗口。

【问题讨论】:

请发布一个完整的最小示例。 谢谢 Eric,我已经更新了问题并发布了一个工作代码,你能检查一下吗?谢谢。 【参考方案1】:

主要变化:

    使用 matplolib.figure 代替 matplotlib.pyplot(并重命名所有相关函数) 添加 self.window 变量 在任何地方都使用 pack()(您不能在一个容器中混合使用网格和打包。)

结果:

__author__ = 'Dania'
import matplotlib
matplotlib.use('TkAgg')
import numpy as np
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.figure import Figure
from Tkinter import *

class mclass:
    def __init__(self,  window):
        self.window = window
        self.box = Entry(window)
        self.button = Button (window, text="check", command=self.plot)
        self.box.pack ()
        self.button.pack()

    def plot (self):
        x=np.array ([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
        v= np.array ([16,16.31925,17.6394,16.003,17.2861,17.3131,19.1259,18.9694,22.0003,22.81226])
        p= np.array ([16.23697,     17.31653,     17.22094,     17.68631,     17.73641 ,    18.6368,
            19.32125,     19.31756 ,    21.20247  ,   22.41444   ,  22.11718  ,   22.12453])

        fig = Figure(figsize=(6,6))
        a = fig.add_subplot(111)
        a.scatter(v,x,color='red')
        a.plot(p, range(2 +max(x)),color='blue')
        a.invert_yaxis()

        a.set_title ("Estimation Grid", fontsize=16)
        a.set_ylabel("Y", fontsize=14)
        a.set_xlabel("X", fontsize=14)

        canvas = FigureCanvasTkAgg(fig, master=self.window)
        canvas.get_tk_widget().pack()
        canvas.draw()

window= Tk()
start= mclass (window)
window.mainloop()

【讨论】:

非常感谢 Eric,它运行良好。有两行我不清楚,你能告诉我这两行是什么意思吗,fig = Figure(figsize=(6,6)) 和 a = fig.add_subplot(111)?谢谢。 我从***.com/questions/4073660/… 开始,他们制作一个图形,然后是一个子图形,然后将图形添加到画布上。希望这会有所帮助。 嘿,我知道我这次谈话迟了几年,但如果我想用命令清除情节,我该怎么做? 我正在尝试制作交互式散点图(带有一些点击事件),但它不适用于 Figure :(

以上是关于Python绘图如何显示中文标题的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 python 代码显示不相关的列而不绘图

如何在 python jupyter notebook 中绘图?

python绘图篇

如何在python中更改绘图/图形的大小[重复]

Python Pyx 绘图:如何更改绘图的颜色背景?

Python 中,matplotlib绘图无法显示中文的问题