PyCharm中matplotlib画图避坑指南:从环境配置到图表美化

发布时间:2026/10/15 13:30:52
PyCharm中matplotlib画图避坑指南:从环境配置到图表美化 做数据可视化的时候我第一次在PyCharm里画图就翻车了——代码照着文档抄结果连个窗口都没弹出来控制台直接报了个错误连图形都看不到。后来才发现问题根本不在绘图代码本身而是PyCharm的解释器、显示后端和字体环境这些看似无关的东西在拖后腿。这篇文章不打算讲那些高深的理论就老老实实聊聊我在PyCharm里用matplotlib画图踩过的坑、总结出来的固定套路以及怎么把一张“能看”的图打磨成“能直接用”的图。无论你是刚接触数据分析的新手还是想提高出图效率的开发者这些内容都是可以直接上手的。1. 画画之前的准备工作1.1 解释器环境和库安装是第一个坎很多人打开PyCharm就急着写import matplotlib.pyplot as plt结果第一行就飘红。这大概率不是库没装而是Project Interpreter选错了。PyCharm里每个项目可以绑定不同的Python环境默认可能是Project Venv但如果你在终端里用系统Python装过库项目里依然会报错。我的习惯是进File - Settings - Project: xxx - Python Interpreter确认当前解释器路径。新建项目时PyCharm一般会自动创建venv虚拟环境这时候打开右下角的Python Packages窗口直接搜索matplotlib安装就行。除了matplotlib建议顺手把pandas、numpy也装好后面处理数据基本离不开它们。注意如果你装的是Anaconda解释器尽量选conda环境的base环境或者单独为项目建一个conda环境。很多国内镜像源环境下pip install matplotlib会因为网络问题卡很久换成国内镜像源或conda通道会快得多。库装好之后验证一下版本。不同版本的matplotlib在某些API上有细微差异比如plt.subplots在旧版本和新版本中行为基本一致但plt.style.use支持的风格列表会随版本增加。建议固定一个大版本我目前常用的是matplotlib 3.x兼容性相对稳定。验证方式很简单在Python Console里敲两行import matplotlib print(matplotlib.__version__)能打印出版本号环境就算通了。这一步看似基础但很多人后面的奇葩问题都是这一步没做好埋下的雷。1.2 认识matplotlib的核心绘图逻辑在动手画图之前有必要先把matplotlib的底层逻辑弄明白。它跟很多绘图库不太一样不是一行代码直接出一张图而是围绕两个核心对象在转Figure画布和Axes坐标系。可以这样类比Figure是一张白纸Axes是白纸上的一块绘图区域。你在图上看到的所有元素——坐标轴、刻度、线条、图例——都是挂在Axes下面的。这一点特别重要因为后面你做的绝大多数自定义操作其实都是在操作Axes对象而不是操作Figure本身。import matplotlib.pyplot as plt fig, ax plt.subplots(figsize(8, 6)) ax.plot([1, 2, 3], [4, 5, 6]) plt.show()你看plt.subplots返回两个东西fig和ax。fig控制整体大小、保存时的分辨率ax控制坐标轴范围、标签、刻度。很多人习惯用plt.plot直接画那是隐式创建Figure和Axes在简单场景下没问题但一旦要画多子图、精细控制坐标轴就会变得很别扭。所以从第一步开始就养成“显式拿fig和ax”的习惯后面的路会顺畅很多。1.3 中文显示和负号问题第一个翻车现场在PyCharm里画图的第一个翻车现场十有八九是中文乱码。默认情况下matplotlib用英文字体渲染所有文本中文字体不匹配就会变成一个个小方块。这个问题不解决后面画再漂亮的图也是白搭。解决办法也不复杂核心思路是“指定一个系统里存在的中文字体”。Windows系统一般有SimHei黑体和Microsoft YaHei微软雅黑macOS有PingFang SC苹方和Heiti SC黑体Linux则取决于你装了什么字体常见的有WenQuanYi Zen Hei。import matplotlib.pyplot as plt plt.rcParams[font.sans-serif] [SimHei] # 根据系统调整 plt.rcParams[axes.unicode_minus] False # 解决负号显示异常第二行axes.unicode_minus设置成False是为了让坐标轴上的负号正常显示。这个问题很隐蔽——如果你不设置负号可能显示成一个莫名其妙的横杠或者框。字体设置最好统一放在一个配置文件里。我在实际项目中会在项目根目录放一个plot_config.py把公共样式全部写到里面每个画图脚本开头import plot_config即可。这样既不用每画一张图都重复设置也方便整体调整配色风格。2. 一步步画出你的第一张图2.1 准备数据从列表到DataFrame画图的第一步是准备数据。初学者最容易犯的错误是直接拿原始数据去画比如从Excel贴几百行到代码里既不处理空值也不做类型转换。这种图即便画出来也往往是错的或者难看的。数据准备的优先级是这样的先确认数据结构再做清洗最后再绘图。举个最常见的例子如果拿到一份CSV文件先读进来看看前几行import pandas as pd df pd.read_csv(sales.csv, encodingutf-8) print(df.head()) print(df.dtypes)df.dtypes能告诉你每列的类型。如果日期列是object类型而不是datetime类型画时间序列图时坐标轴就会乱掉。很多画图异常排查到最后都发生在数据预处理阶段而不是绘图阶段。数据的存储结构上我建议尽量用pandas的DataFrame来管理而不是一堆零散的列表。DataFrame的好处是自带列名、索引和分组能力而且matplotlib可以直接从DataFrame取列绘图非常方便plt.plot(df[月份], df[销售额])这一点在后面画多组对比图、做分面图时尤其有用。把数据整理好了绘图只是一行命令的事数据没整理好画图就是一场灾难。2.2 创建画布和坐标系接下来是创建画布。推荐永远使用plt.subplots()它的功能远比字面上丰富。fig, ax plt.subplots(figsize(8, 6), dpi100)figsize控制画布大小单位是英寸。(8, 6)在屏幕上看是适中的尺寸但放论文或者汇报PPT里可能需要更大比如(12, 8)。dpi控制分辨率。屏幕显示100就行如果是打印或者投稿建议300。有一个很容易忽略的点figsize和dpi一起决定了最终图片的像素尺寸。如果你需要一张宽1920像素的图那么figsize(10, 7.5)加上dpi192就能得到也可以反过来推算。养成这个思维习惯后面保存图片时就不会出现“看起来模糊”的问题。拿到fig和ax之后所有绘图操作都基于ax来做。用ax.plot而不是plt.plot用ax.set_xlabel而不是plt.xlabel。这样做的好处是逻辑清晰所有元素都明确归属到指定的坐标系上在多子图场景下绝无污染。2.3 绘制并添加基础修饰数据准备好、画布创建好之后就可以开始画了。先从一个最简单的折线图开始import matplotlib.pyplot as plt import numpy as np x np.linspace(0, 10, 50) y np.sin(x) fig, ax plt.subplots(figsize(8, 5)) ax.plot(x, y, colorcrimson, linewidth2, markero, markersize4, labelsin(x)) ax.set_xlabel(时间 (s), fontsize12) ax.set_ylabel(振幅, fontsize12) ax.set_title(正弦波示例, fontsize14) ax.legend() ax.grid(True, linestyle--, alpha0.6) plt.show()关键参数拆解color颜色名或者十六进制色值。matplotlib支持的颜色名有限但支持任意十六进制值比如#FF5733自由度更大。linewidth线宽推荐2左右。太细了打印出来看不清太粗了遮挡数据趋势。marker数据点标记。折线图可以不用标记但如果数据点不多加标记能更清楚表达样本位置。label曲线的标签配合legend()才会显示图例。grid网格线。设置alpha0.6可以让网格不那么刺眼。linspace(0, 10, 50)生成了0到10之间的50个点这样正弦曲线就是平滑的。这里用numpy生成数据是个好习惯——直接用Python自带的range生成小数会出问题因为range只支持整数。这一套流程熟练之后你会发现所有的基础图表套路都是一样的准备数据、创建画布、调用绘图函数、设置坐标轴、标题、图例、网格。区别只在绘图函数的具体参数上。3. 四种常用图形的实际场景与配置要点3.1 折线图观察趋势变化的标配折线图主要用于展示数据随时间或序列变化的趋势。比如某电商平台每天的订单量、某服务器每小时的请求数这些都是典型的折线图场景。绘制多组对比折线时有一个特别容易忽略的细节如果两条线的数值范围差异悬殊直接画在同一组坐标轴上数值小的曲线会被压成一条直线。这种情况有三种处理方式。第一种把两组数据归一化统一到同一个量纲第二种用双Y轴左边画一组右边画另一组第三种如果两组数据分属完全不同的业务场景干脆拆成两个子图。fig, ax1 plt.subplots(figsize(10, 6)) ax2 ax1.twinx() # 创建共享X轴的第二个Y轴 ax1.plot(df[月份], df[订单量], colorsteelblue, label订单量) ax2.plot(df[月份], df[客单价], colororange, linestyle--, label客单价) ax1.set_ylabel(订单量, colorsteelblue) ax2.set_ylabel(客单价, colororange) plt.show()twinx()在业务数据报告里用得非常多但也容易被误用。用双Y轴之前一定要想明白两个指标之间是否有对应的对比关系如果只是数字层级差距大可以通过对数变换解决优先用对数坐标而不是盲目上双轴。因为双Y轴如果处理不当很容易误导读者对趋势强弱的判断。3.2 柱状图对比类数据的清晰表达柱状图适用于离散类别的对比比如不同地区的销量、不同产品的退货率、不同季度的利润。柱状图在matplotlib里有两种形态bar竖直柱和barh水平柱。类别名称比较长的时候水平柱更合适因为类别文字可以横着排版不需要旋转。categories [产品A, 产品B, 产品C, 产品D] values [220, 340, 280, 190] fig, ax plt.subplots(figsize(8, 5)) bars ax.bar(categories, values, color#4C72B0, edgecolorwhite, width0.6) ax.set_ylabel(销量) ax.set_title(各产品季度销量) plt.show()width0.6设置柱子宽度。默认值是0.8但实际看起来往往偏宽尤其在柱子很多的时候0.6左右更舒服。edgecolor设置柱子边缘颜色白色边缘能让柱子在深色填充下更有边界感。做对比柱状图时如果想在柱体上方标出具体数值一个常见做法是ax.bar_label(bars)。这个API在matplotlib 3.4以上版本可用非常方便不用费劲去算文本坐标。ax.bar_label(bars, fmt%.0f, padding3)fmt控制文本格式%.0f表示不保留小数padding表示数值文本离柱顶的距离。这个方法开发效率极高值得记住。3.3 散点图与直方图探索数据分布的两把刀散点图用来观察两个变量之间的关系比如广告投入与销售额、页面访问量与下单量。它的核心参数是alpha透明度因为数据多点密集时不透明散点会互相遮挡看不清密度分布。fig, ax plt.subplots(figsize(8, 6)) scatter ax.scatter(df[广告费用], df[销售额], cdf[利润], cmapviridis, alpha0.7, s50) cbar fig.colorbar(scatter) cbar.set_label(利润) ax.set_xlabel(广告费用) ax.set_ylabel(销售额) plt.show()这里用cdf[利润]让散点颜色随利润变化配合cmapviridis生成渐变色再用colorbar加上颜色条。这样一张散点图同时表达了三个维度的信息横轴、纵轴、颜色。这是探索性数据分析中常用到的技巧信息量比普通散点图大很多。直方图用于查看单变量的数值分布。plt.hist的bins参数值得说一说默认10个柱子通常不够数据分布细节被掩盖但bins设得太大又会看到太多噪声。我的经验是先用binsauto让numpy自动估计再根据业务含义微调。最省事的方式是用seaborn的histplot来画它底层还是matplotlib但bin的默认策略更智能。4. 图形细节打磨让图从“能用”变为“能看”4.1 坐标轴范围和刻度是默认陷阱先看一个我曾经踩过的坑。有一回画曲线数据范围是0到5但是图里有个点的坐标是6结果matplotlib自动把坐标轴上限扩到7。看起来没什么问题但图显得空白区域过大趋势线只占了一小部分。这时候就需要主动设置坐标轴范围。ax.set_xlim(0, 6) ax.set_ylim(-1.5, 1.5)set_xlim和set_ylim在自动范围不理想时必须手动干预。除了范围刻度也是值得精细控制的对象。默认的刻度位置和标签格式有时并不适合当前场景。比如横轴是日期默认会显示十几个日期字符串挤成一团。解决办法是控制刻度数量和显示格式。常用做法是用matplotlib.dates模块import matplotlib.dates as mdates ax.xaxis.set_major_locator(mdates.MonthLocator(interval1)) ax.xaxis.set_major_formatter(mdates.DateFormatter(%Y-%m))MonthLocator控制每隔多少个月显示一个刻度DateFormatter控制显示格式为“年-月”。这样横轴瞬间清爽多了。4.2 图例和样式信息完整性的最后拼图图例是很多人容易马虎的地方。默认的ax.legend()会放在“最佳”位置这个位置由matplotlib内部算法决定但并不是每次都合理。特别是图例跟曲线重叠的时候必须手动指定位置ax.legend(locupper right, frameonTrue, shadowTrue) ax.legend(locupper left)loc的可选值有upper right、lower left、upper center等也可以直接传入元组坐标比如(0.02, 0.98)表示相对于坐标轴坐标系的(2%, 98%)处。frameon控制图例边框shadow虽说是美观增强但多数风格下我建议关掉显得干净。样式方面matplotlib自带多套风格可以直接调用plt.style.use(seaborn-v0_8-whitegrid) plt.style.use(ggplot) plt.style.use(grayscale)ggplot风格模仿R语言绘图包颜色浓郁、背景网格清晰seaborn风格整体更淡雅网格线更细。多尝试几种风格找出最适合你业务场景的那一款。我个人通常在数据分析和汇报演示两种场合用不同风格分析时用白底带网格方便读细节汇报时用浅色底无网格简洁大气。4.3 保存图像时最容易忽略的细节画完图之后保存和展示是收尾动作。PyCharm里直接运行脚本plt.show()会弹出GUI窗口但在某些无GUI的环境里比如远程调试plt.show()不会产生任何效果。这种情况要改用plt.savefig()保存到文件。fig.savefig(output.png, dpi300, bbox_inchestight)dpi300出版级质量屏幕展示用150就够。bbox_inchestight自动裁剪掉图片周围多余的空白。很多人不设这个结果保存出来的图四周一大圈白边插进文档里非常难看。保存格式上如果图片需要继续编辑建议存SVG矢量格式如果是插入Word或者PPTPNG就够了如果是论文投稿一般要求TIFF或者EPS。还有一个容易被坑的点plt.show()和plt.savefig()同时出现时务必先savefig再show。有些情况下如果先show后保存保存下来的图片可能是空白。这个问题的原因是show()执行时会重置图像对象顺序搞反了就吃大亏。5. 图像问题排查我把踩过的坑都列出来了5.1 常见错误一览表我把这几年在PyCharm里画图遇到的坑整理成了一张表。每一条都是自己踩过之后才记住的看一遍能省不少时间。症状原因解法运行代码没有图形窗口弹出PyCharm的显示后端设置不对在Settings - Tools - Python Scientific里关闭“Show plots in tool window”或手动指定后端plt.switch_backend(TkAgg)中文显示成方块默认字体不含中文字形rcParams[font.sans-serif] [SimHei]负号显示成特殊符号默认unicode负号与字体不兼容rcParams[axes.unicode_minus] False多张图只显示最后一张每次循环没有新建Figure循环内使用fig, ax plt.subplots()而不是复用同一个Axes图例中曲线标签不显示绘图时未指定label参数在plot、bar等函数里加上label名称然后调用legend()图片保存后空白show()和savefig()顺序错误先savefig后show画出的曲线只有一条直线横轴数据未排序或者传参错误打印x和y的shape进行检查确认数据长度一致且对应关系正确坐标轴刻度重叠刻度太多、标签太长减少刻度数量或旋转标签plt.xticks(rotation45)5.2 三个很隐蔽但坑过我的小细节第一个是循环画图时忘记清空当前图表。在循环体里画图如果不用plt.close(fig)或者每次新建fig, ax后一张图会画在前一张图的重复坐标轴之上越画越乱。最佳实践是把“创建fig/ax、绘图、保存、关闭”全流程放在循环体内部。第二个是关于数据中NaN值的处理。如果DATE列有缺失值直接plot会出现断线或者整条线消失。处理方式是在绘图前用df.dropna(subset[日期, 销售额])清理干净。这个很基础但一遇到真实数据就特别容易被忽略。第三个是关于多个子图时坐标轴自动共享的问题。用subplots(nrows2, ncols2, sharexTrue, shareyTrue)创建多子图时加入sharex和sharey后子图会共享坐标轴范围。这在对比实验时非常有用但如果你没意识到它共享了范围就会疑惑为什么每个子图的数据看起来都在同一数值区间。看清楚参数想清楚自己是否需要共享这个一定要主动决策。5.3 PyCharm里的三个提速技巧熟手和新手的区别很多时候不在于知不知道函数名而在于工作流效率。下面三个小技巧值得单独记一下。把公共配置放在.pth文件或者自启动脚本里。每次新建画图脚本自动加载字体、配色、默认dpi不用重复敲配置。用altshifte选中代码块后执行而不是整脚本跑一遍。在调试图片时这个操作能让你只重画改动的部分不用把前一步数据准备代码全部重跑。如果某个图形要反复画封装成函数。比如plot_sales_line(df, group_col, value_col)内部实现全部绘图逻辑返回fig和ax。后续调用两行代码搞定也方便统一调整样式。提示如果你的项目里图片数量特别多最好把图片保存路径统一管理起来比如每天生成一个日期目录。这样回溯时找图特别快别问我怎么知道的——我曾在三个月后翻一个项目文件夹看到一片报错和重名文件当场决定写个统一保存函数。6. 实战体会把一份销售数据变成一张合格的可视化图6.1 一个完整的业务分析绘图实例为了把前面所有知识点串在一起我模拟了一个非常常见的业务场景某公司有三个渠道线上商城、线下门店、电话销售需要对比过去半年的销售额变化趋势。数据是一个CSV文件包含日期、渠道、销售额三列。import pandas as pd import matplotlib.pyplot as plt plt.rcParams[font.sans-serif] [SimHei] plt.rcParams[axes.unicode_minus] False df pd.read_csv(sales_data.csv, encodingutf-8) df[日期] pd.to_datetime(df[日期]) pivot df.pivot_table(index日期, columns渠道, values销售额, aggfuncsum) fig, ax plt.subplots(figsize(12, 6)) pivot.plot(axax, linewidth2, markero, markersize4) ax.set_title(三大渠道近六个月销售额对比, fontsize14) ax.set_ylabel(销售额) ax.legend(title渠道) ax.grid(True, linestyle--, alpha0.5) fig.savefig(渠道销售对比.png, dpi300, bbox_inchestight) plt.show()这段代码把几个关键技巧全部用上了pd.to_datetime统一日期类型pivot_table做透视表得到适合直接绘图的宽表pivot.plot(axax)把pandas的便捷接口和matplotlib的精细控制结合起来。输出的图标题清晰、图例明确、网格辅助、尺寸适中完全可以放到月初经营分析会上去讲。透视表这一步是这份数据处理的精华。原始数据是长表格式一行一条记录绘图需要宽表格式一行一个日期、每一列是一个渠道。pivot_table自动做了聚合汇总这个操作比手动分组循环调用groupby再逐个绘制要高效得多。6.2 从个人经验出发的几点总结在PyCharm里做数据可视化这件事说到底是三条经验第一环境问题永远是第一优先级解释器、字体、后端三件套没搞定就画图画不痛快第二把绘图做成一个流程而不仅是代码——准备数据、创建画布、绘制、修饰、保存每一步都有对应的常见问题第三遇到问题不要慌先看数据形状再看坐标系对象绝大多数坑都能在这两步里找到线索。从纯技术角度看matplotlib并不难难的是把图表表达的意思和业务问题对齐——画之前想清楚“这幅图要给谁看、说明什么”画出来才有价值。这个思考习惯才是数据可视化真正值钱的部分。希望这篇文章能帮你少走一些弯路。如果你在PyCharm里画图时遇到过其他奇奇怪怪的问题欢迎在评论区聊聊说不定下次我整理问题排查时你的案例就会出现在表里。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询