Pandas绘图速查手册:12种原生画法搞定90%数据可视化场景
1. 为什么数据分析时我会第一时间用 df.plot()1.1 它和 Matplotlib 到底什么关系先说句坦白的话最早我看不上 Pandas 画图。Pandas 的.plot接口看起来就是给初学者做练习用的真正出图还得靠 Matplotlib、Seaborn 这些专门做可视化的库。这个偏见在一次临时复盘需求里被打破了。那天同事丢给我一张几十行的宽表里面有销售额、订单量、客单价等七八个指标要求“五分钟后投屏看趋势”。我下意识写了这么一段df.plot(subplotsTrue, figsize(16, 10)) plt.tight_layout()五分钟内每个指标一张折线图整整齐齐排出来图例、刻度、索引全都不用管。从那一刻起我开始认真研究 Pandas 的原生绘图能力也理解了它的定位Pandas 绘图不是 Matplotlib 的替代品而是 Matplotlib 的“自动挡”封装。它帮你做了几件最琐碎的事自动把 DataFrame 的索引变成 X 轴列名变成图例。自动处理多列数据每个系列一种颜色自动添加 legend。返回 Matplotlib 的Axes对象画完还能继续用plt/ax.set_xxx精修。kind参数一行切换图表类型语法统一。换句话说Pandas 绘图是“毛坯房交付”Matplotlib 是“装修队”。你随时可以通过 Pandas 快速拿到基础结构再调用 Matplotlib 做精细化装修。1.2 哪些场景该用 Pandas 绘图哪些场景该换工具用了一年多我给自己定了三个使用标准优先用 Pandas 绘图的场景探索性数据分析快速看分布、看趋势、看异常。Jupyter Notebook 里做中间结果展示不是最终报告。临时给业务方一个“差不多能看”的图重点在信息而非版式。数据宽表结构清晰列不多于 8 个画子图或折线都很好读。劝你换工具的场景需要高度定制可视化比如绘图、桑基图、地图叠加。需要大量交互、缩放、悬浮提示建议直接上 Plotly 或 ECharts。需要复杂统计模型可视化比如回归曲线置信区间、聚类边界。一张图里塞几万个点Pandas 的scatter仍然可用但性能和表现力都不如专门库。我的结论是Pandas 原生绘图是数据处理全链路里性价比最高的一环。它不追求惊艳但保证你从“拿到数据”到“看出问题”的路径最短。这篇文章就把 Pandas 里能让你一键出图的全部原生类型都过一遍一共 12 种常用画法全部用手边数据能直接跑。2. 一张表看完全部 12 类画法与各自适用场景2.1 准备一份足够折腾的测试数据为了把 12 种画法讲清楚我需要一份同时包含数值、类别、日期和缺失值的测试数据。直接构造一份模拟门店销售数据import numpy as np import pandas as pd import matplotlib.pyplot as plt # 解决中文显示问题Windows 试 SimHeimacOS 试 PingFang SC plt.rcParams[font.sans-serif] [SimHei, PingFang SC, Noto Sans CJK SC] plt.rcParams[axes.unicode_minus] False np.random.seed(42) date_rng pd.date_range(2024-01-01, periods60, freqD) df pd.DataFrame({ 日期: date_rng, 销售额: np.random.randn(60).cumsum() 200, 订单量: np.random.randint(20, 80, 60), 客单价: 200 np.random.randn(60) * 30, 门店: np.random.choice([A区门店, B区门店, C区门店], 60), 是否促销: np.random.choice([True, False], 60, p[0.3, 0.7]), }) # 故意加入缺失值后面能展示问题 df.loc[10:12, 客单价] np.nan df.head()这段数据里有日期、连续数值、整型数值、类别、布尔值还埋了几个缺失值。接下来所有画法都以这份数据为基础这样图表之间可以互相呼应。2.2 12 种画法的总览速查表Pandas 的DataFrame.plot()并没有 12 个kind参数官方kind参数支持的值是line、bar、barh、area、pie、scatter、box、hexbin、hist、kde/density这 10 类。我标题里说的 12 类是把高频使用的两个组合画法stacked堆叠和subplots多子图也算进来了这样加起来正好 12 种能覆盖日常需求的原生画法。序号调用方式图表名称最适合的业务场景1df.plot(kindline)折线图时间序列趋势、连续指标变化2df.plot(kindbar)垂直柱状图类别数量对比、排名比较3df.plot(kindbarh)水平柱状图类别名很长、数量较多时的对比4df.plot(kindarea)面积图展示各分组累计贡献随时间的变化5df.plot(kindpie)饼图少类别的静态占比通常在 5 类以内6df.plot(kindscatter)散点图两个连续变量之间的相关性7df.plot(kindbox)箱线图数值分布、离群点检测8df.plot(kindhist)直方图单变量分布形态、频数统计9df.plot(kindkde)核密度图平滑概率密度曲线适合多组对比10df.plot(kindhexbin)六边形密度图大数据量散点用色块反映局部密度11df.plot(subplotsTrue)多子图多列指标并列展示共享坐标结构12df.plot(stackedTrue)堆叠图展示各部分占整体比例的动态变化表格里kind参数和 boolean 参数混在一起我专门把它们分开写是因为很多人只记kind而忘了 Pandas 还有很多绘图参数能组合出完全不同的图表结构。下面几章就按业务场景顺序逐组讲透。3. 五类业务图表实操Line、Bar、Barh、Area、Pie3.1 折线图先看清趋势再做双轴折线图是最常用也最容易小看的一张图。直接用df.plot(kindline)时Pandas 会把所有数值列都画到一张图里包括日期索引。但是当列和列之间量纲不同比如“销售额”几百、“订单量”几十画在一起订单量的趋势会被压成一条直线。我的习惯是先画单指标折线看趋势再决定要不要双轴。df.set_index(日期)[销售额].plot( kindline, figsize(10, 4), title每日销售额趋势, markero, markersize3, gridTrue, ) plt.tight_layout()折线图里适合配gridTrue因为用户看趋势图时通常会顺手用视觉比对几个取值点。marker参数在小样本量时很实用但日更数据动辄几百个点开 marker 反而变成密密麻麻的斑点建议超过 50 个点就不要加marker了。当你想把“销售额”和“订单量”放在同一张图里对比正确的做法是用secondary_y开双轴df.set_index(日期).plot( y[销售额], secondary_y[订单量], figsize(12, 5), title销售额与订单量双轴对比, ) plt.tight_layout()这个写法比手动先画两个axes简洁得多。Pandas 会自动为右侧 Y 轴生成独立的刻度和单位还会在图例里用括号标注主轴和次轴。注意双轴容易让人误读两条曲线的比较关系如果只是单纯想强调各自趋势建议还是用subplotsTrue分上下两图更诚实。3.2 柱状图和水平柱状图类别对比的两种姿势柱状图的核心场景是“按类别聚合后比大小”。比如按门店汇总销售额马上能看出谁强谁弱store_sales df.groupby(门店)[销售额].sum().sort_values(ascendingFalse) store_sales.plot( kindbar, figsize(8, 4), rot0, title各门店销售额汇总, color[#4C72B0, #55A868, #C44E52], ) plt.ylabel(总销售额) plt.tight_layout()这里要注意三个细节rot0让 X 轴刻度标签水平显示不然 Pandas 默认会把中文类别标签旋转 45 度容易折行。对groupby结果先sort_values柱状图默认不会排序必须先排序再画否则排名看起来是乱的。当只有一列数据时Pandas 仍然会尝试按 colormap 给每根柱子分配不同颜色这会传递“这些柱子是不同分类”的错误信息所以手动传入color数组统一颜色。水平柱状图barh的适用场景很直接类别名称太长的时候。比如“A区门店”只有 4 个字看不出来但换成“华东A区旗舰店”、“华东B区社区店”垂直柱状图的 X 轴标签就会挤成一条黑带。store_sales.sort_values().plot( kindbarh, figsize(8, 5), title各门店销售额排行水平, color#4C72B0, ) plt.xlabel(总销售额) plt.tight_layout()一个很实在的经验水平柱状图底部按数值排序后会天然形成一个从上到下逐渐递增的“台阶”比垂直柱状图更容易让读者快速看出排名适合汇报场景。3.3 面积图和饼图份额变化 VS 静态占比面积图是我做“份额随时间变化”时的首选。先把宽表变成一张每个门店一列的透视表然后直接画pivot_store df.pivot_table( index日期, columns门店, values销售额, aggfuncsum ).fillna(0) pivot_store.plot( kindarea, figsize(12, 5), stackedTrue, alpha0.7, title各门店销售额面积堆叠图, ) plt.ylabel(销售额) plt.tight_layout()面积图的默认stackedTrue也就是说上面的曲线是累计值每一层厚度代表该分部的绝对值。看图时重点关注两层之间的间距间距越大说明该分部贡献越大。alpha0.7是必要的否则不同色块之间会有难以辨认的叠影。当某个门店数据为零时Pandas 会直接让对应色块厚度归零不会报错这比手动处理缺失值要省心。饼图在数据分析圈名声不太好但业务方还是很爱看。Pandas 画饼图有一个比较绕的地方如果直接在包含多个数值列的 DataFrame 上调用kindpie并且不指定y它会为每一列单独生成一张饼图。要想只画一个占比一定要明确指定ystore_sales.plot( kindpie, y销售额, figsize(6, 6), autopct%.1f%%, legendFalse, title门店销售额占比, ) plt.ylabel() plt.tight_layout()autopct传一个格式化字符串就能在扇区上显示百分比不用额外写循环遍历 label。legendFalse是因为 Pandas 默认会为饼图生成一个容易重叠的图例类别的名字通常直接标在扇区旁边就够了。超过 5 个类别的饼图建议直接放弃人眼对角度差异的分辨能力比对着色块面积差得多。4. 四类统计图表实操Scatter、Box、Hist、KDE4.1 散点图别把分类变量传给 c 参数散点图用来探索两个连续变量的关系。比如分析“客单价”和“销售额”是否相关df.plot.scatter( x客单价, y销售额, figsize(8, 6), alpha0.6, title客单价与销售额散点关系, ) plt.tight_layout()Pandas 的scatter没有自动处理缺失值的机制。上面数据里人为加了几条空的客单价画出来的图直接少了这几个点。如果缺失值占比不大这是可接受的但如果缺失值占了三成直接画散点图会严重漏掉部分样本应该先考虑填充策略而不是闷头画图。c参数是散点图里最容易被误用的地方。很多人想把第三维用颜色表示第一反应是写c门店Pandas 会报错或者画出完全看不懂的映射。c参数期望的是数值序列或者颜色序列不是分类标签列。想让不同门店显示不同颜色需要手动构造颜色映射color_map {A区门店: #4C72B0, B区门店: #55A868, C区门店: #C44E52} df[门店颜色] df[门店].map(color_map) df.plot.scatter( x客单价, y销售额, cdf[门店颜色], alpha0.7, figsize(8, 6), title分门店查看客单价与销售额, ) plt.tight_layout()这样点位上每个点的颜色才会按门店区分但图例不会自动出现。想要图例要么手动添加代理图元要么临时把每个门店单独画一次。在探索阶段我通常不纠结图例因为颜色分布已经能看出聚类轮廓。4.2 箱线图使用 by 参数快速分组箱线图是把数值分布浓缩到一张图里的最快速方式。Pandas 里两种写法df[[销售额, 订单量]].plot( kindbox, figsize(8, 5), title销售额与订单量分布对比, ) plt.tight_layout()这种方式针对多个数值列画并列箱体用来对比不同指标的量级和离散程度。但更常见的需求是按门店分组看同一指标这时候by参数比kind更重要df.boxplot( column销售额, by门店, figsize(8, 5), gridTrue, ) plt.title(各门店销售额分布) plt.suptitle() # 去掉 Pandas 自动加的上层标题 plt.tight_layout()注意我在这里用了df.boxplot这是 Pandas 专门的 boxplot 接口。如果使用df.plot(kindbox, by门店)语法上也能跑但控制不如df.boxplot直接。箱线图里最值得看的是中位线和箱体的高度关系如果业务指标有明显离群点箱线图一眼就能找出来。Pandas 的 boxplot 默认不标注离群样本的具体索引想要精确定位还需借助描述统计df.groupby(门店)[销售额].describe()这个方法纯用 Pandas 就能完成不必非要用 Matplotlib 画异常值高亮。4.3 直方图和 KDE分布刻画的两条路线直方图的目的是看单变量的分布形态。我用两个连续列对比时最喜欢把它们叠加在同一张图里df[[销售额, 订单量]].plot( kindhist, bins30, alpha0.6, figsize(10, 5), title销售额与订单量分布对比, ) plt.tight_layout()两个问题必须提醒直方图的bins在不同取值范围的变量上表现差异很大。“销售额”在 180 到 220 之间“订单量”在 20 到 80 之间直接叠加会看到胖瘦极不对称的两个柱群。想对比形态建议先用MinMaxScaler或(x - x.min()) / (x.max() - x.min())把变量缩放到同一量纲再看直方图才有意义。alpha0.6很重要否则第二个柱群会把第一个完全遮住。直方图还有一个常用变体概率密度直方图。df[销售额].plot( kindhist, bins30, densityTrue, figsize(8, 4), title销售额概率密度直方图, ) df[销售额].plot( kindkde, color#C44E52, linewidth2, labelKDE 核密度曲线, ) plt.tight_layout()densityTrue将 y 轴从“频次”变为“概率密度”这样直方图和 KDE 曲线就能叠在同一坐标系里。这个组合在报告里很常见先看原始分布的柱状形态再看平滑曲线的偏态和峰态。KDE 曲线的核心参数是bw_method带宽。它的默认值在大多数业务数据上表现尚可但当数据分布有明显多峰形态时默认带宽会把峰抹平。我通常先试bw_method0.3再对比默认值选择更贴近实际业务语义的那条曲线。带宽越小曲线越“毛糙”带宽越大曲线越“光滑”没有绝对正确只有业务上是否合理。4.4 注意Pandas 的 density 是 kde 的别名很多人不知道 Pandas 里kinddensity和kindkde完全等价。官方文档里density就是kde的别名两者参数完全一致。写代码时可以混用但团队协作项目里最好统一使用kde因为这个词在统计学语境中更标准也更容易被同事理解。5. Hexbin 和组合布局两颗经常被忽略的彩蛋5.1 hexbin海量散点不糊成一团散点图一旦数据量过万就会变成一团墨点每个坐标位点上的点密度完全看不出来。hexbin把画布切成六边形网格用填充色深浅表示网格内的点的数量适合做“大数据量下的密度视图”。np.random.seed(1) big_x np.random.randn(20000) big_y np.random.randn(20000) * 0.5 big_x * 0.3 big_df pd.DataFrame({x: big_x, y: big_y}) big_df.plot.hexbin( xx, yy, gridsize20, figsize(8, 5), title2万个点的六边形密度图, cmapviridis, ) plt.tight_layout()gridsize控制六边形网格的密度gridsize20表示横向大约 20 个六边形。数值越小网格越粗适合快速看概貌数值越大网格越细适合局部精细密度。颜色图cmap建议使用色觉障碍友好的viridis或magma不要用jet这类彩虹色。hexbin还支持用C参数做聚合加权。默认CNone每个网格的值是点的计数如果传入另一个连续列再配reduce_C_functionnp.mean就能得到每个网格内该列的均值。这在分析地理数据或者维度联合分布时非常有用比如“每个月销售额在哪个区间密度最高”。5.2 subplotsTrue一列一张子图多列宽表放到同一张折线图里如果量纲不同就会互相压扁。subplotsTrue会把每一列单独分配到一张小图里但保持相同的索引和格式。df.set_index(日期)[[销售额, 订单量, 客单价]].plot( subplotsTrue, layout(3, 1), figsize(10, 9), sharexTrue, title[销售额趋势, 订单量趋势, 客单价趋势], ) plt.tight_layout()layout控制子图排列方式。三列数据用(3, 1)竖排每张图都共享日期 X 轴。sharexTrue让三张子图对齐了 X 轴刻度方便上下对照同一时间范围。还有sharey参数同量纲指标建议打开量纲差异大则建议关闭。一个很容易踩坑的点当subplotsTrue时title参数接收的是一个列表而不是一个字符串。如果只传一个字符串Pandas 只给第一张子图加标题后面全是空标题。我最早就在这里卡了十几分钟。5.3 secondary_y 与 stacked双轴和堆叠的细节这两个参数虽然不改变图表类型但改变图表的语义结构。我在 3.1 讲过secondary_y做双轴的操作这里重点说堆叠。堆叠图用的最多的是两种堆叠柱状图和堆叠面积图。堆叠柱状图的业务语义是“同一类别下各组件的构成”。例如要展示每个门店下“正常销售”和“促销销售”两部分订单量promo_pivot df.pivot_table( index门店, columns是否促销, values订单量, aggfuncsum, ).rename(columns{True: 促销, False: 非促销}) promo_pivot.plot( kindbar, stackedTrue, figsize(8, 5), rot0, title各门店促销与非促销订单量, ) plt.ylabel(订单量) plt.tight_layout()stackedTrue配合bar就是堆叠柱状图配合area就是堆叠面积图。从代码角度看差异很小但业务解读完全不同堆叠柱状图适合对比各门店内部构成堆叠面积图更适合展示各构成随时间滚动的累计趋势。这也印证了 2.2 表里为什么要把组合参数单独算作两种画法。6. 图不好看90% 是数据没收拾干净6.1 索引决定 X 轴日期与排序问题Pandas 绘图最容易被忽视的行为是默认的 X 轴永远是 DataFrame 的索引。这意味着如果索引不是连续的日期或者带重复值画出来的折线图会非常怪。比如我前面一直用df.set_index(日期)再绘图。如果不设置索引直接df.plot(y销售额)Pandas 会用 0、1、2 这样的整数行号作为 X 轴。数据恰好按日期排序时这个整数轴勉强等于日期序列但一旦有缺失日期或需要按周展示整数轴就乱了。因此时间序列绘图的标准流程是df[日期] pd.to_datetime(df[日期]) df df.set_index(日期).sort_index()先用pd.to_datetime统一日期格式再set_index最后sort_index保证时间顺序正确。这三步看起来基础但能避免折线图时间乱序导致的回跳毛刺。6.2 类型不对画出来的全是乱码DataFrame 里显示的是数字不代表底层类型是数值型。最常见的是从 CSV 读入后某列因为混入了空字符串被解析成 object这时候kindline会直接报错。画图前做一次类型体检非常有必要df.dtypes如果看到object类型但内容全是数字用pd.to_numeric转换df[客单价] pd.to_numeric(df[客单价], errorscoerce)errorscoerce会把无法解析的值变成 NaN而不是让整个程序中断。这样至少图还能画缺失值再单独处理。分类变量如果要影响柱状图顺序可以设置成category类型并指定categories的顺序这样不用额外构造排序。6.3 缺失值会让图形“断骨”缺失值在各类图中的表现差异很大折线图遇到中间缺失Pandas 默认不会自动连起来会直接出现断口。柱状图遇到缺失则表现为整个柱子消失X 轴刻度还在。散点图遇到缺失相关样本被安静地剔除图上少一个点。面积图遇到缺失Pandas 在堆叠时会强行补零面积形状可能产生突变。所以画图前先决定缺失值策略而不是让 Pandas 用默认行为“背锅”。最常用的三个方法df[销售额].ffill() # 用上一时刻的数值填充适合缓慢变化的业务指标 df[销售额].bfill() # 用下一时刻的数值回填注意未来数据泄露风险 df[销售额].fillna(df[销售额].median()) # 用中位数填充适合稳定分布时间序列预测任务里只能用ffill不能用bfill因为回填意味着用了未来数据会造成极强的数据泄露。这是我踩过最痛的一个坑。6.4 长表转宽表用 pivot_table 喂给绘图接口Pandas 绘图接口设计得更偏向“宽表”每一列是一个系列。但大多数原始业务数据是“长表”同一列里有很多个类别。所以在画堆叠图和分组图之前通常要做一步透视pivot df.pivot_table( index日期, columns门店, values销售额, aggfuncsum, fill_value0, )pivot_table把“日期 × 门店 → 销售额”变成长表得到“日期为行、每个门店为一列”的宽表。直接用这个结果画line、area、bar都能一次性得到多系列图表。表结构不干净的时候绘图代码写得再漂亮都没用这是所有可视化的前提。7. 从数据探索到成品图主题、标注、导出与 pd.plotting7.1 用 Matplotlib 风格和 rcParams 统一画风Pandas 的默认图表风格比较“实验室”但业务汇报时需要更干净的画风。最简单的办法是借用 Matplotlib 的预设风格plt.style.use(seaborn-v0_8-whitegrid)whitegrid提供浅灰背景和白色网格线在投影场景下比默认的白底黑框柔和。Pandas 绘图完全继承 Matplotlib 的当前rcParams所以先设置风格再画图就会自动生效。常用的其他风格还有ggplot、fivethirtyeight、bmh。注意不同 Pandas / Matplotlib 版本中seaborn风格的名称可能带-v0_8后缀也可以直接用不带后缀的旧名称试一下。7.2 用返回的 Axes 对象做精细化标注Pandas 的.plot()会返回一个 MatplotlibAxes对象subplotsTrue时返回ndarray。这意味着你可以先快速画图再精修坐标轴。ax df.set_index(日期)[销售额].plot(figsize(12, 5), title每日销售额趋势) ax.set_ylabel(销售额元) ax.axvline(pd.Timestamp(2024-01-20), color#C44E52, linestyle--, linewidth1) ax.annotate( 促销开始, xy(pd.Timestamp(2024-01-20), df[销售额].max()), xytext(pd.Timestamp(2024-01-05), df[销售额].max() * 0.95), arrowpropsdict(arrowstyle-, color#4C72B0), )这条竖线标注和箭头注释是 Pandas 绘图本身不支持的但拿到ax之后随时可以叠加。这也是 Pandas 绘图的精髓快速生成主体再按需精修。7.3 保存成可交付的图表保存图表时我强烈建议用bbox_inchestight和dpi两个参数fig ax.figure fig.savefig(销售额趋势.png, dpi200, bbox_inchestight)bbox_inchestight会自动裁剪掉图表边缘的多余留白不会出现标题或坐标轴标签被切掉的情况。dpi200能在屏幕上颗粒感不强且尺寸不至于过大。如果是要印刷或投到高清大屏dpi建议提高到 300。注意df.plot()内部会调用plt.gca()去拿当前坐标轴所以在调用plt.savefig前如果执行过多次绘图可能会保存到最后一张图。更稳妥的做法是一开始就用ax df.plot(...)拿到对象再从ax.figure保存。7.4 pd.plotting 里的四张高级诊断图Pandas 原生绘图还有一个常被忽略的模块pd.plotting它不通过kind调用却是 Pandas 家族里的“隐藏绘图功能”。from pandas.plotting import autocorrelation_plot, lag_plot, parallel_coordinates, bootstrap_plotautocorrelation_plot(series)自相关图用来判断时间序列是否存在自相关性是写趋势模型的快速诊断。lag_plot(series)滞后散点图把当前值与前一天值一一对应画散点看短期依赖关系。parallel_coordinates(frame, class_column)平行坐标图把多维变化映射到一根轴上适合观察分类样本在高维空间里的区分度。bootstrap_plot(series, size100, samples500)自助抽样分布图通俗讲就是用重抽样看统计指标的稳定性。如果只看 12 类基础图可能会错过这些诊断利器。我一般在建模之前跑一遍这几张图比逐列算describe()更直观能发现数据中不少非线性模式和自相关信号。8. 我替你们踩过的三个坑字体、日期刻度、图例位置8.1 中文字体显示成方块这是中文用户最普遍的问题。Pandas 调用 Matplotlib 绘图后中文字符经常显示成一个个小方块原因是 Matplotlib 默认字体库不包含中文字形。最直接的解决方式import matplotlib.pyplot as plt plt.rcParams[font.sans-serif] [SimHei] plt.rcParams[axes.unicode_minus] Falseaxes.unicode_minus是解决负号显示为方块这个连带问题的关键。如果SimHei在你的系统里不存在可以换成PingFang SCmacOS或Noto Sans CJK SCLinux。还有一个更稳的办法是手动加载字体文件。有些服务器上没有中文字体上面的列表形同虚设就需要找到字体文件路径后通过font_manager注册from matplotlib import font_manager font_manager.fontManager.addfont(/usr/share/fonts/noto-cjk/NotoSansCJK-Regular.ttc) plt.rcParams[font.sans-serif] [Noto Sans CJK JP]注册之后rcParams里填的字体名不一定是文件名可以用f.name打印实际字体家族名再填进去。这个坑很冷门但在 Docker 环境里基本必踩。8.2 日期坐标轴自动刻度太密/太疏Pandas 画日期折线图时X 轴的刻度密度是自动决定的。当数据跨度是两个月时它有时隔两三天标一个日期整张图底下的刻度标签密密麻麻挤成一团有时又隔很久标一个看不出局部变化。手动干预是最终解法import matplotlib.dates as mdates ax df.set_index(日期)[销售额].plot(figsize(12, 5)) ax.xaxis.set_major_locator(mdates.DayLocator(interval7)) ax.xaxis.set_major_formatter(mdates.DateFormatter(%m-%d))DayLocator(interval7)让 X 轴每 7 天标一个主刻度DateFormatter(%m-%d)把刻度标签格式化为“月-日”。如果数据跨度超过半年建议把interval改成 30 或者用MonthLocator。你也可以只设置ax.xaxis.set_major_locator(plt.MaxNLocator(10))让 Matplotlib 自动选择不大于 10 个的刻度。这个方法比较省心但无法控制间隔是否符合日历周期。8.3 图例长在图上遮住数据数据列多时Pandas 自动生成的图例经常会盖住图上的关键趋势线。很多人反复调loc参数发现不管怎么调都在图内。把图例挪到图外是更干净的方案ax.legend(locupper left, bbox_to_anchor(1.02, 1), frameonFalse)bbox_to_anchor(1.02, 1)表示图例向右平移出绘图区loc定义锚点对齐方式。这样图例占的是图表右侧的空白位置不遮数据。需要配合plt.tight_layout()使用否则图例可能被裁掉。如果你的图表宽度不够记得在figsize里留出右侧空白。当图例项很多时还可以加ncol2分两列展示减小图例占用的纵向高度。8.4 单列柱状图配色混乱的怪现象这是我花过最多时间排查的一个“非报错式”问题。同样是kindbarDataFrame 有两列时每一列一种颜色看起来正常DataFrame 只有一列时Pandas 会把这根柱子拆成多个分类按 colormap 给每一根柱子分配不同的颜色。图看起来像是给每个类别单独配了色实际上却是同一种指标的重复展示配色带有误导性。解决方法是显式指定颜色df.groupby(门店)[销售额].sum().plot( kindbar, color[#4C72B0] * 3, )或者用df.plot.bar(color#4C72B0)。这类细节不改影响不大但一旦要把图放进正式报告颜色语义错了就是大问题。我在实际项目里通常把一套自己的配色常量放在项目配置里画图前直接引入不用每次重新想颜色。最后补一句个人体会Pandas 绘图的价值不在“炫技”而在压缩从数据到结论的时间。十二种画法背下来以后我大部分探索性分析不再需要单独打开画图工具一条kind参数切来切去就能覆盖九成需求。以后有人问起 Pandas 能不能画图你可以直接把这份速查手册发给他。
上一篇/下一篇内容由系统自动关联
返回资讯列表 →