Matplotlib是Python中最常用的可视化工具之一,可以轻松创建海量类型的2D图表和一些基本的3D图表。本文主要介绍学习Matplotlib时遇到的一些挑战,为什么要使用Matplotlib,并推荐学习使用Matplotlib的一个步骤。简介对于新手来说,闯入Python可视化世界有时会令人沮丧。Python有许多不同的可视化工具,选择正确的工具有时是一个挑战。例如,即使在两年后,这个《Overview of Python Visualization Tools》仍然是引导人们访问该网站的热门帖子之一。在那篇文章中,我对matplotlib投下了一些阴影,并且在分析过程中不再使用它。然而,在使用了pandas、scikit-learn、seaborn等python工具和其他数据科学堆栈之后,丢弃matplotlib感觉有点为时过早。老实说,之前我对matplotlib了解不多,也不知道如何在我的工作流程中有效地使用它。现在我已经花时间学习了其中一些工具,以及如何使用matplotlib,我开始将matplotlib视为不可或缺的工具。这篇文章将展示我如何使用matplotlib,并为刚入门或没有时间学习matplotlib的用户提供一些建议。我坚信matplotlib是python数据科学堆栈的重要组成部分,希望本文能帮助您了解如何使用matplotlib进行自己的可视化。为什么对matplotlib有负面评论?在我看来,新用户在学习matplotlib时面临某些挑战有几个原因。首先,matplotlib有两个接口。第一个基于MATLAB并使用基于状态的接口。第二个是面向对象的接口。为什么这两个接口超出了本文的范围,但重要的是要知道有两种方法可以使用matplotlib进行绘图。造成这两个界面混淆的原因是,鉴于stackoverflow社区和谷歌搜索中可用的丰富信息,新用户在面对看起来有些相似但并不相同的问题的多种解决方案时可能会感到困惑。让我从我自己的经历说起。回顾我的旧代码,一堆matplotlib代码的混合——这让我很困惑(即使我写了它)。要点matplotlib的新用户应该学习使用面向对象的接口。matplotlib的另一个历史挑战是一些默认样式选项相当不吸引人。在R世界中,ggplot可用于生成一些非常酷的图,相比之下,matplotlib的选项看起来有点难看。好消息是matplotlib2.0有了更漂亮的风格,并且能够对可视化内容进行主题化,非常方便。使用matplotlib我认为第三个挑战是,在绘制某些东西时,你应该纯粹使用matplotlib或者使用像pandas或seaborn这样的工具构建在它之上,你会感到困惑。任何时候都可以有多种做事方式,对于新手或刚接触matplotlib的用户来说,遵循正确的路径可能具有挑战性。将这种混淆与两个不同的API联系起来是解决方法。为什么坚持使用matplotlib?尽管存在这些问题,我还是很感激有matplotlib,因为它非常强大。这个库允许创建几乎任何你能想象到的可视化。此外,围绕它还有丰富的python工具生态系统,许多更高级的可视化工具都使用matplotlib作为基础库。在python数据科学堆栈中进行任何工作都需要对如何使用matplotlib有基本的了解。这是本文其余部分的重点-介绍有效使用matplotlib的基本方法。基本前提如果您没有本文以外的任何背景知识,建议按照以下步骤学习如何使用matplotlib:学习基本的matplotlib术语,尤其是什么是绘图和坐标轴。使用它的习惯从基本的pandas图开始你的可视化学习使用seaborn进行更复杂的统计可视化使用matplotlib自定义pandas或seaborn可视化大多数术语非常简单,但要记住的要点是Figure是最终图像,其中可能包含一个或多个轴。轴代表一个分区。一旦您了解了这些以及如何通过面向对象的API访问它们,就可以开始执行以下步骤。这种术语知识还有另一个好处,当你在网上看东西时,你就有了一个起点。如果您花时间了解这一点,您将不会了解matplotlibAPI的其余部分。此外,python的许多高级包,如seaborn和ggplot,都依赖于matplotlib。因此,了解了这些基础知识后,学习更强大的框架就更容易了。***,我并不是说您应该避免使用更好的工具,例如ggplot(又名ggpy)、bokeh、plotly或altair。我只是认为你需要从对matplotlib+pandas+seaborn的基本了解开始。一旦您了解了基本的可视化技术,您就可以探索其他工具并根据您的需要做出明智的选择。入门本文的其余部分作为介绍性教程,介绍了在pandas中创建基本可视化以及使用matplotlib自定义最常用的项目。一旦了解了基本流程,进一步的定制就相对简单了。我将重点介绍我遇到的最常见的绘图任务,例如标记轴、调整限制、更新绘图标题、保存图片和调整图例。如果您想继续学习,链接https://github.com/chris1610/pbpython/blob/master/notebooks/Effectively-Using-Matplotlib.ipynb上的附注和其他详细信息应该非常有用。准备开始,我首先导入库并读入一些数据:raw=true")df.head()这是2014年的销售交易数据。为了使数据简短,我将汇总数据,以便我们可以看到前十名客户的总购买量和总销售额。为了清楚起见,我还重命名了图中的列。top_10=(df.groupby('name')['extprice','quantity'].agg({'extprice':'sum','quantity':'count'}).sort_values(by='extprice',ascending=False))[:10].reset_index()top_10.rename(columns={'name':'Name','extprice':'Sales','quantity':'Purchases'},inplace=True)下面是数据处理的结果。现在数据已格式化为一个简单的表格,让我们看看如何将这些结果绘制成条形图。如前所述,matplotlib有许多不同的样式可用于渲染绘图,使用plt.style.available查看您的系统上可用的样式。plt.style.available['seaborn-dark','seaborn-dark-palette','fivethirtyeight','seaborn-whitegrid','seaborn-darkgrid','seaborn','bmh','classic','seaborn-colorblind'、'seaborn-muted'、'seaborn-white'、'seaborn-talk'、'grayscale'、'dark_background'、'seaborn-deep'、'seaborn-bright'、'ggplot'、'seaborn-paper','seaborn-notebook','seaborn-poster','seaborn-ticks','seaborn-pastel']这么好用的一个样式:plt.style.use('ggplot')鼓励大家尝试不同的样式,看看你喜欢哪些。现在我们已经准备好进行更好??的查看,第一步是使用标准pandas绘图函数绘制数据:top_10.plot(kind='barh',y="Sales",x="Name")我建议先绘图使用pandas是构建可视化效果的一种快速简便的方法。由于你们中的大多数人可能已经在pandas中完成了一些数据处理/分析,所以让我们从基本绘图开始。自定义绘图假设您对绘图的要点感到满意,下一步就是自定义它。使用pandas绘图功能进行自定义(例如添加标题和标签)非常简单。但是,您可能会发现您的需求以某种方式覆盖了此功能。这就是为什么我建议养成这样做的习惯:fig,ax=plt.subplots()top_10.plot(kind='barh',y="Sales",x="Name",ax=ax)与原来的相同,但我们添加了对plt.subplots()的额外调用并将ax传递给绘图函数。你为什么要这样做?还记得我说过访问坐标轴和图形在matplotlib中至关重要吗?这就是我们在这里所做的。任何未来的定制都将通过ax或fig对象完成。由于pandas快速绘图,我们可以完全访问matplotlib。我们现在能做什么?让我用一个例子来告诉你。此外,命名约定使得将其他人的解决方案改编为适合您独特需求的解决方案变得非常简单。假设我们要调整x限制并更改一些轴标签?现在坐标轴保存在ax变量中,我们有很多控制权:fig,ax=plt.subplots()top_10.plot(kind='barh',y="Sales",x="Name",ax=ax)ax.set_xlim([-10000,140000])ax.set_xlabel('TotalRevenue')ax.set_ylabel('客户');下面是一个快捷方式,你可以用来改变标题和两个标签:fig,ax=plt.subplots()top_10.plot(kind='barh',y="Sales",x="Name",ax=ax)ax.set_xlim([-10000,140000])ax.set(title='2014Revenue',xlabel='TotalRevenue',ylabel='Customer')为了进一步验证这个方法,图片也可以调整大小。figsize可以通过plt.subplots()函数以英寸为单位定义。您还可以使用ax.legend().set_visible(False)删除图例。图,ax=plt.subplots(figsize=(5,6))top_10.plot(kind='barh',y="Sales",x="Name",ax=ax)ax.set_xlim([-10000,140000])ax.set(title='2014Revenue',xlabel='TotalRevenue')ax.legend().set_visible(False)您可能出于多种原因想要调整此图。最难看的是总收入数字的格式。Matplotlib可以通过FuncFormatter帮我们实现。此函数将用户定义的函数应用于一个值,并返回一个格式整齐的字符串以放置在轴上。这是一个货币格式化函数,可以优雅地处理数十万范围内的美元格式化:defcurrency(x,pos):'Thetwoargsarethevalueandtickposition'ifx>=1000000:return'${:1.1f}M'.format(x*1e-6)return'${:1.0f}K'.format(x*1e-3)现在我们有了一个格式化函数,我们需要定义它并将它应用到x轴上。这是完整的代码:fig,ax=plt.subplots()top_10.plot(kind='barh',y="Sales",x="Name",ax=ax)ax.set_xlim([-10000,140000])ax.set(title='2014Revenue',xlabel='TotalRevenue',ylabel='Customer')formatter=FuncFormatter(currency)ax.xaxis.set_major_formatter(formatter)ax.legend().set_visible(False)漂亮,以及您可以如何灵活地定义自己的问题解决方案的一个很好的例子。我们要探索的最后一个自定义功能是向绘图添加注释。要绘制垂直线,可以使用ax.axvline()。要添加自定义文本,您可以使用ax.text()。在此示例中,我们将绘制一条平均线并显示三个新客户的标签。下面是将它们放在一起的完整代码和注释。#Createthefigureandtheaxesfig,ax=plt.subplots()#Plotthedataandgettheaveragedtop_10.plot(kind='barh',y="Sales",x="Name",ax=ax)avg=top_10['Sales'].mean()#setlimitsandlabelsax.set_xlim([-10000,140000])ax.set(title='2014Revenue',xlabel='TotalRevenue',ylabel='Customer')#Addalinefortheaverageax.axvline(x=avg,color='b',label='Average',linestyle='--',linewidth=1)#Annotatethenewcustomersforcustin[3,5,8]:ax.text(115000,cust,"NewCustomer")#Formatthecurrencyformatter=FuncFormatter(currency)ax.xaxis.set_major_formatter(formatter)#Hidethelegendax.legend().set_visible(False)虽然这可能不是令人兴奋的绘制方式,但它显示了使用此方法时您拥有多少权限。图形和图像到目前为止,我们所做的所有更改都是单一图形。幸运的是,我们还可以在图表之上添加多个图形并使用各种选项保存整个图像。如果我们决定将两个图放在同一张图像上,我们应该对如何做到这一点有一个基本的了解。首先,创建图形,然后创建轴,然后将它们一起绘制。我们可以用plt.subplots()来完成:fig,(ax0,ax1)=plt.subplots(nrows=1,ncols=2,sharey=True,figsize=(7,4))在这个例子中,使用nrows和ncols指定大小,新用户更清楚。在示例代码中,您经常会看到像1,2这样的变量。我认为使用命名参数可以使以后查看代码时更容易理解。使用sharey=True以便yaxis共享相同的标签。这个例子也很好,因为各个轴被解包为ax0和ax1。使用这些坐标轴,您可以像上面的示例一样绘制图形,但在ax0和ax1上分别绘制一个图形。#Getthefigureandtheaxesfig,(ax0,ax1)=plt.subplots(nrows=1,ncols=2,sharey=True,figsize=(7,4))top_10.plot(kind='barh',y="Sales",x="名称",ax=ax0)ax0.set_xlim([-10000,140000])ax0.set(title='Revenue',xlabel='TotalRevenue',ylabel='Customers')#Plottheaverageasverticallineavg=top_10['Sales'].mean()ax0.axvline(x=avg,color='b',label='Average',linestyle='--',linewidth=1)#Repeatfortheunitplottop_10.plot(kind='barh',y="Purchases",x="Name",ax=ax1)avg=top_10['Purchases'].mean()ax1.set(title='Units',xlabel='TotalUnits',ylabel='')ax1.axvline(x=avg,color='b',label='Average',linestyle='--',linewidth=1)#Titlethefigurefig.suptitle('2014SalesAnalysis',fontsize=14,fontweight='bold');#Hidethelegendsax1。legend().set_visible(False)ax0.legend().set_visible(False)到目前为止,我一直在使用jupyternotebook在%matplotlib内联指令的帮助下显示图形。但很多时候,数字需要以特定的格式保存,并与其他内容一起显示。Matplotlib支持以多种不同格式保存文件。可以使用fig.canvas.get_supported_filetypes()查看系统支持的格式:fig.canvas.get_supported_filetypes(){'eps':'EncapsulatedPostscript','jpeg':'JointPhotographicExpertsGroup','jpg':'JointPhotographicExpertsGroup','pdf':'PortableDocumentFormat','pgf':'PGFcodeforLaTeX','png':'PortableNetworkGraphics','ps':'Postscript','raw':'RawRGBAbitmap','rgba':'RawRGBAbitmap','svg':'ScalableVectorGraphics','svgz':'ScalableVectorGraphics','tif':'TaggedImageFileFormat','tiff':'TaggedImageFileFormat'}由于我们有fig对象,我们可以使用多个选项保存图像:fig.savefig('sales.png',transparent=False,dpi=80,bbox_inches="tight")上面的代码将图像保存为具有不透明背景的png。还指定了分辨率dpi和bbox_inches="tight"以尽量减少多余的空白。结论希望这个过程帮助您了解如何在日常数据分析中更有效地使用matplotlib。如果您在进行分析时养成了使用此方法的习惯,您应该能够快速自定义您需要的任何图像。作为奖励,我提供了一个总结所有概念的快速指南。希望这有助于将本文联系在一起,并为将来的使用提供方便的参考。
