Loading... <div class="tip share">请注意,本文编写于 273 天前,最后修改于 166 天前,其中某些信息可能已经过时。</div> > 这是简单进阶教程系列第三篇,本系列文章主要介绍那些可以很快上手的进阶库。 说起数据可视化,大多数人第一反应是matplotlib,我以前也尝试过。但是,一方面是matplotlib设置稍微有点复杂,另一方面是它有点丑(也可能是我不会调),思来想去还不如直接用excel作图呢,于是一直也没有python作过图。但是后来发现了这样一款神器`Plotly Express`,不仅设置简单,刚好和我比较熟练的DataFrame联系起来了。而且颜值巨高,那还说什么,学起来。 先看看它的颜值有多高: [https://pan.yanshu.work/article/pic.html](https://pan.yanshu.work/article/pic.html) ## 安装导入 ```python pip install plotly_express # 安装 import plotly.express as px # 导入 ``` ## IDE中无法显示图像? Plotly貌似只能在Jupyter中直接显示,而在代码编辑器中,如`Spyder`,无法直接显示。一个间接的解决方案是利用浏览器显示,下面是一个示例。(来源于[http://liyangbit.com/pythonvisualization/Plotly-Express-IDE/](http://liyangbit.com/pythonvisualization/Plotly-Express-IDE/)) ```python import plotly.express as px import plotly plotly.offline.init_notebook_mode(connected=True) iris = px.data.iris() iris_plot = px.scatter(iris, x='sepal_width', y='sepal_length', color='species', marginal_y='histogram', marginal_x='box', trendline='ols') plotly.offline.plot(iris_plot) ``` Plotly生成的图像居然是可交互式的,太完美了。 ## 使用方法 ### 散点图 ```python import plotly.express as px df = px.data.iris() fig = px.scatter(df, x="sepal_width", y="sepal_length") fig.show() # Jupyter中有用 ```  **按种类上色** ```python fig = px.scatter(df, x="sepal_width", y="sepal_length", color="species") ```  **在散点图上添加频率分布直方图,散点图右添加rug图** ```python fig = px.scatter(df, x="sepal_width", y="sepal_length", color="species", marginal_y="rug", marginal_x="histogram") ```  **添加趋势线** ```python fig = px.scatter(df, x="sepal_width", y="sepal_length", color="species",trendline="ols") ```  **给每个点添加一个范围** ```python df["e"] = df["sepal_width"]/100 fig = px.scatter(df, x="sepal_width", y="sepal_length", color="species", error_x="e", error_y="e") ```  其中`error_x`是x方向的范围,`error_y`是y方向的范围 **多重分类散点图** ```python import plotly.express as px df = px.data.tips() fig = px.scatter(df, x="total_bill", y="tip", facet_row="time", facet_col="day", color="smoker", trendline="ols", category_orders={"day": ["Thur", "Fri", "Sat", "Sun"], "time": ["Lunch", "Dinner"]}) ``` 横向按周几分,纵向按时间分,category_orders可以不加,但是没有这个参数,它就会按默认的顺序排列  ### 气泡图 本质上和散点图一样,加上`size='col_name'`即可生成 ```python df = px.data.gapminder() fig = px.scatter(df.query("year==2007"), x="gdpPercap", y="lifeExp", size="pop", color="continent", hover_name="country", log_x=True, size_max=60) ``` 就是按照2007年数据,气泡大小与人口有关(size="pop"),气泡显示标题为国家名(color="continent"),对x轴取对数,气泡最大60  **动态气泡图** ```python df = px.data.gapminder() fig = px.scatter(df, x="gdpPercap", y="lifeExp", animation_frame="year", animation_group="country", size="pop", color="continent", hover_name="country", facet_col="continent", log_x=True, size_max=45, range_x=[100,100000], range_y=[25,90]) ``` 最重要的参数就是`animation_frame="year"`,它表示按年份绘制动态气泡图,至于`animation_group`,说实话我不知它有啥用,删掉好像也没有影响 下面图其实是动图,但我懒得录制gif了……  ### 矩阵散点图 **矩阵散点图** ```python df = px.data.iris() fig = px.scatter_matrix(df) ``` 简单来说就是把df中所有变量(列名)按照不同方式进行组合然后作散点图  **矩阵散点图选定几个变量** ```python fig = px.scatter_matrix(df, dimensions=["sepal_width", "sepal_length", "petal_width", "petal_length"], color="species") ``` 有时候我只想看其中几个变量的相关关系  ### 三元散点图 ```python df = px.data.election() fig = px.scatter_ternary(df, a="Joly", b="Coderre", c="Bergeron", color="winner", size="total", hover_name="district", size_max=15, color_discrete_map = {"Joly": "blue", "Bergeron": "green", "Coderre":"red"} ) ```  ### 3D散点图 ```python df = px.data.election() fig = px.scatter_3d(df, x="Joly", y="Coderre", z="Bergeron", color="winner", size="total", hover_name="district", symbol="result", color_discrete_map = {"Joly": "blue", "Bergeron": "green", "Coderre":"red"}) ``` symbol="result"指的是按结果设置不同的图例形状  ### 雷达散点图 ```python df = px.data.wind() fig = px.scatter_polar(df, r="frequency", theta="direction", color="strength", symbol="strength") ```  ### 平行图 **平行坐标图** 平行坐标图主要分析多维变量之间的关系 ```python df = px.data.iris() fig = px.parallel_coordinates(df, color="species_id", labels={"species_id": "Species", "sepal_width": "Sepal Width", "sepal_length": "Sepal Length", "petal_width": "Petal Width", "petal_length": "Petal Length", }, color_continuous_scale=px.colors.diverging.Tealrose, color_continuous_midpoint=2) ``` label是个字典,主要是把变量名改成容易理解的标签,可以去掉,那么图上显示的就是变量名。 color_continuous_scale貌似是指色域范围,感觉没有必要掌握,color_continuous_midpoint也一样。(这两参数都是可以去掉的)  **平行类别图** ```python df = px.data.tips() fig = px.parallel_categories(df, color="size", color_continuous_scale=px.colors.sequential.Inferno) ```  ### 折线图 ```python df = px.data.gapminder() fig = px.line(df, x="year", y="lifeExp", color="continent", line_group="country", hover_name="country", line_shape="spline", render_mode="svg") ``` `line_group`参数去掉后,线的密集程度明显增加了。 `line_shape="spline"`大概是折线的样式, `render_mode="svg"`这次必须带这个参数  ### 三元折线图 ```python df = px.data.election() fig = px.line_ternary(df, a="Joly", b="Coderre", c="Bergeron", color="winner", line_dash="winner") ``` line_dash="winner",使折线变成不同样式(实线、虚线等)  ### 3D折线图 ```python df = px.data.election() fig = px.line_3d(df, x="Joly", y="Coderre", z="Bergeron", color="winner", line_dash="winner") ```  ### 雷达折线图 ```python df = px.data.wind() fig = px.line_polar(df, r="frequency", theta="direction", color="strength", line_close=True) ``` line_close=True指的是折线是否首尾相接  ### 面积图 ```python df = px.data.gapminder() fig = px.area(df, x="year", y="pop", color="continent", line_group="country") ```  ### 等高线图 ```python df = px.data.iris() fig = px.density_contour(df, x="sepal_width", y="sepal_length") ```  ### 热力图 ```python df = px.data.iris() fig = px.density_heatmap(df, x="sepal_width", y="sepal_length") ```  ### 条形图 ```python df = px.data.tips() fig = px.bar(df, x="sex", y="total_bill", color="smoker", barmode="group") ``` `barmode="group"`指的是是否按照`smoker`分开展示。用图说明吧,下面第一张图是带参数的,第二张图是不带参数的。   ### 雷达条形图 ```python df = px.data.wind() fig = px.bar_polar(df, r="frequency", theta="direction", color="strength", template="plotly_dark") ```  ### 直方图 ```python df = px.data.tips() fig = px.histogram(df, x="total_bill", y="tip", color="sex", marginal="rug", hover_data=df.columns) ``` `hover_data=df.columns`展示相应数据的所有信息,必须与marginal连用才有效 类似地,可以添加`barmode="group"`参数以分开展示  ### 带状图 ```python df = px.data.tips() fig = px.strip(df, x="total_bill", y="time", orientation="h", color="smoker") ``` orientation="h",水平方向绘图  ### 箱型图 ```python df = px.data.tips() fig = px.box(df, x="day", y="total_bill", color="smoker", notched=True) ``` notched=True是下面的形状,如果notched=False,那么就完全变成蜡烛图了。  ### 小提琴图 ```python df = px.data.tips() fig = px.violin(df, y="tip", x="smoker", color="sex", box=True, points="all", hover_data=df.columns) ``` box=True为是否展示里面的小箱子,points="all"为是否展示小提琴旁边的点,hover_data=df.columns为是否详细展示所有数据点信息  ### 地图 用Poltly Express制作地图,可以离线用的只有世界地图,其他类型的地图需要申请token(大概是在这里申请的:[https://www.mapbox.com/](https://www.mapbox.com/))。或者自己制作,可以在github上找如“China geojson”类型的json数据。等我以后尝试一下看怎么做 给个例子: ```python df = px.data.gapminder() fig = px.choropleth(df, locations="iso_alpha", color="lifeExp", hover_name="country", animation_frame="year", range_color=[20,80]) ```  ## 总结 基本用法`px.pic_type(df,x='col_name',y='col_name')` 注意:三元图(三元折线图、三元散点图),x,y变成a,b,c了 3D图是xyz 雷达图是r,theta **图片种类:** * scatter,散点图 * scatter_matrix,矩阵散点图 * scatter_ternary,三元散点图 * scatter_3d,3D散点图 * scatter_polar,雷达散点图 * line,折线图 * line_ternary,三元折线图 * line_3d,3D折线图 * line_polar,雷达折线图 * area,面积图 * density_contour,等高线图 * density_heatmap,热力图 * bar,条形图 * bar_polar,雷达条形图 * histogram,直方图 * strip,带状图 * violin,小提琴图 * box,箱形图 **通用参数**: * `template="plotly_dark"`,图片模板 * `color="col_name"` 按某一列的种类进行着色 * `color_discrete_map = {"col_name": "blue", "col_name": "green", "col_name":"red"}`,设定不同的颜色 * `symbol="col_name"`按某一列的种类设置不同的形状 * `marginal_x="pic_type"`在图片上方添加一个同样数据做出来的其他类型图 * `marginal_y="pic_type"`在图片右方添加一个同样数据做出来的其他类型图 * `labels=dict`把变量名改成标签 * `facet_row="col_name"`横向分成小图 * `facet_col="col_name"`纵向分成小图 * `category_orders=dict`小图按顺序排列(可选) * `color_continuous_scale=px.colors.sequential.Viridis`,`color_continuous_midpoint=2`都是颜色参数,不要也可 * `range_x=[100,100000]`x轴范围,y轴类似 * `hover="col_name"`,元素标题(比如设置为country,那么折线图中每一条线的标题即国家名,气泡图中每个气泡的标题是国家名) * `render_mode="webgl"`不知道是个啥东西,有些好像必须带这个参数比如折线图第一个案例 **散点图参数** * `trendline="ols"`趋势线 * `error_x='col_name'`是给点加上x方向的范围 * `error_y='col_name'`是给点加上y方向的范围 **气泡图参数**(其实还是scatter) * `size="col_name"`,气泡大小影响因素 * `log_x=True`,对x轴取对数 * `size=60`,气泡最大大小 * `animation_frame="col_name"`动态气泡图按指定参数动(比如年份)(加上这个参数就能动了) **矩阵散点图参数** * `dimensions=list` 选定的参数列表 **折线图参数** * `line_group="col_name"` * `line_shape="spline"` * `render_mode` * `line_dash="col_name"`最好和color的值一样,使折线变成不同样式(如虚线)(包括三元折线图) **面积图参数** * `line_group="col_name"` **条形图、直方图参数** * `barmode="group"`,是否分开展示? * `marginal="pic_type"`在图片上方添加一个同样数据做出来的其他类型图 * `hover_data=df.columns`展示相应数据所有信息 **带状图参数** * `orientation="h"`,水平方向绘图 **箱型图参数** * `notched=True` **小提琴图** * `box=True`为是否展示里面的小箱子 * `points="all"`为是否展示小提琴旁边的点 * `hover_data=df.columns`为是否详细展示所有数据点信息 ## 图片保存 **保存为html** ```python fig.write_html("file.html") fig.write_html("file.html",include_plotlyjs='cdn') # 意味着你生成的html中引用了官方的CDN资源,这样会减小html大小,但同时也使其离线不可用。 ``` **保存为静态图片** 首先你需要安装`orca`,官方说可以pip或conda安装 ```python conda install -c plotly plotly-orca ``` 但是我并没有成功,因此只能下载二进制文件安装了。 首先在[https://github.com/plotly/orca/releases](https://github.com/plotly/orca/releases)找到适合你系统的版本,我的是windows,因此就下载`windows-release.zip`。(其他系统参考[https://github.com/plotly/orca](https://github.com/plotly/orca)) 然后解压缩,点击exe文件安装。 安装完毕后桌面会出现`orca`的快捷图标,右键打开属性菜单,复制`起始位置`的路径,然后添加该路径到系统变量。 打开cmd,输入`orca --help`,若能正常输出则说明安装成功。 接着重启编辑器,就可以成功生成图片啦。 ```python fig.write_image("fig1.png") # 生成png格式 fig.write_image("fig1.jpeg") # 生成jpeg格式 fig.write_image("ifig1.webp") # 生成webp格式 fig.write_image("fig1.svg") # 生成svg格式 fig.write_image("fig1.pdf") # 生成pdf格式 fig.write_image("fig1.eps") # 这个好像还需要再安装poppler,算了算了 ``` > png,jpg,webp都好模糊啊,还不如我在html上截图呢…… ## 报错解决 ```python ImportError: cannot import name 'factorial' ```  原因:`Plotly_Express`依赖了scipy这个库的一个misc模块,但是由于最新版本的scipy中,scipy.misc 已经迁移到 scipy.special 里面了,所以提示无法找到 解决方案: 一、scipy降级成1.2.1 ```python pip install -i https://pypi.tuna.tsinghua.edu.cn/simple scipy==1.2.1 ``` 二、按照提示的路径,把scipy.misc都改成 scipy.special > 比如我的路径是C:\Users\51445\Anaconda3\Lib\site-packages\statsmodels,只要把这个文件夹拖到`VScode`中然后批量替换即可<hr class="content-copyright" style="margin-top:50px" /><blockquote class="content-copyright" style="font-style:normal"><p class="content-copyright">版权属于:雁陎</p><p class="content-copyright">本文链接:<a class="content-copyright" href="https://www.sitstars.com/archives/84/">https://www.sitstars.com/archives/84/</a></p><p class="content-copyright">转载时须注明出处及本声明</p></blockquote> Last modification:August 9th, 2020 at 01:29 pm © 允许规范转载