【数据分析师---数据可视化】第二章:plotly绘图进阶篇(地图可视化,动态数据可视化)


手动反爬虫,禁止转载: 原博地址 https://blog.csdn.net/lys_828/article/details/119491338(CSDN博主:Be_melting)

 知识梳理不易,请尊重劳动成果,文章仅发布在CSDN网站上,在其他网站看到该博文均属于未经作者授权的恶意爬取信息

1 地图可视化

1.1 模块安装与地理数据基础知识

folium模块就是用来获取地理坐标以及围栏信息的模块,绘制图形时使用plotly模块。folium模块属于第三方模块,需要手动安装,可以选择在jupyter notebook中安装也可以选择在命令行中安装,如果系统中已经有该模块,那么输出结果如下
在这里插入图片描述
如果直接安装folium模块失败,需要准备三个前置关联模块:GDALShapelyFiona,三个模块依照顺序进行安装,建议使用wheel文件进行安装,在wheel网站下载对应的python版本和电脑系统的文件后,直接在jupyter notebook中进行安装,多个模块的安装中间使用空格隔开
请添加图片描述
关于地理可视化相关的地理数据类型需要先介绍一下,具体包含三类:点、线、面数据。地理数据的绘制前提是在某一坐标系下进行,比如一个点,在二维地图上就是由x,y对应的数据决定。点数据常用作地点标记,线数据多用于距离标记,面数据多用于构建地理围栏(就是绘制出地图上的某部分区域)
在这里插入图片描述

1.2 地图数据GeoJSON数据生成

关于地理信息数据对应的数据结构为GeoJSON,也就是上图中右边花括号中代码部分,在实际中并不需要自己动手一个单词一个单词的敲,而是通过第三方界面或者folium模块进行绘制生成

首先看第三方界面如何生成地图数据,GeoJSON地图数据生成网站,对应的网址界面如下。
在这里插入图片描述
(1)生成点数据

点击地图右上方竖向的标记按钮(红框所在位置),然后再点击想要标记的地点,鼠标点击具体位置后,就会在右侧的代码区生成对应的数据。默认就有对应的地理数据类型和位置的经纬度
在这里插入图片描述
此外再次点击添加的标记点,会弹出标签卡片,可以在上面进行位置信息的标注,比如添加此地是一座学校,对应SMU(Shanghai Martime University),右侧原来properties对应的值为空,此时就会把添加的标注信息进行更新(前三名标注信息是标签卡自带的默认选项,第四个是手动添加的,如果还要进行添加信息可以点击下面的add就行,然后填写完毕后点击Save进行保存)
在这里插入图片描述
(2)生成线数据

点击地图右上方的线段按钮后在地图上标记一段距离(要结束绘制的时候将鼠标放置在最后一个点后点击鼠标左键即可),最后在右侧会自动生成线数据,已经对应的经纬度信息
在这里插入图片描述
(3)生成面数据

地图右上方的多边形的按钮是绘制面数据的按钮,需要进行描边最后首尾相连生成面数据。如果要以正方形选取某一区域的面数据,可以点击下方的正方形按钮,直接拖动就可以绘制,最后右边会生成对应的地理数据类型和每一个点的经纬度信息
在这里插入图片描述
地理数据的保存,点击地理图像的上方Save按钮,下拉菜单可以选择保存数据的格式,常见的有GeoJSON和CSV
在这里插入图片描述
最终数据保存在本地,文件打开后的内容如下(就是原网页右侧的代码信息)
在这里插入图片描述
然后直接使用folium模块生成地理信息数据,代码如下

from folium.plugins import Draw
import folium

#获取地图
m = folium.Map()
#获取绘图对象
draw = Draw(export=True, filename="test.geojson")
#将绘图对象添加到地图中
draw.add_to(m)
#最后显示地图
m

输出结果为:(左侧就是刚刚网页地图右侧很熟悉的绘图工具栏,右侧有个export按钮)
在这里插入图片描述
比如还是对刚刚的大学进行一个区域的地理信息的绘制,如下(如果已经有test.geojson文件,再进行一次地图数据的生成,会默认在test后面增加(1)的标识,也就是生成test(1).geojson文件,接着绘制生成数据文件时候,文件名就会以此类推)
请添加图片描述
生成的文件打开后内容如下(后缀名也是geojson,里面的数据格式和上面的文件中内容是统一的)在这里插入图片描述
直接使用folium模块就直接满足了地理信息数据的获取,这种还是直接在jupyter notebook中直接通过绘制获得不需要打开第三方网站,但是也就少了添加标签卡的信息的功能,所以两者进行综合决策,最终根据需求选择要生成数据的方式

1.3 绘制轮廓地图可视化

读入地图信息数据,和自己手头上待展示的数据,比如分析全国电商的销量情况,绘制各省份的销售占比,因此自然匹配的地理信息就是全国各省份的数据。可以选择按照上面介绍的方式进行自我绘制,也可以使用别人绘制好的GeoJson直接加载。当要进行全国或者某省市的地理可视化时候推荐使用别人已经绘制好的GeoJson文件(可以百度搜索,测绘局获取),当研究的地理区域具有独特性,就需要自己自己手动绘制。故这里直接加载全国的地理信息数据

import json
with open('china_geojson.json') as file:
    china = json.load(file)

china

输出结果如下:(查看china变量的结果,可以发现和之前通过手动绘制的格式一模一样,而且中国地图绘制的是多边形区域,地理数据类型就对应着ploygon
在这里插入图片描述
有了地理信息数据后,就可以加载自己要分析的数据,读取本地的Csv文件,只显示前五条数据
最核心的一步就是进行图形的绘制

fig = px.choropleth(geo,geojson=china,locations='Regions',scope="asia",color='followerPercentage')
fig

输出结果如下:(第一个参数就是DataFrame,然后第二参数就是指定地理信息数据,第三个参数就是DataFrame数据中待匹配字段名称,scope参数代表地图底图显示的区域,默认是显示全球,这里指定亚洲,就是下图中灰色的区域,最后一个参数就是添加颜色)
请添加图片描述
使用choropleth功能绘制的地图,就是相当于标定一个在原来的地图上标定一个区域来显示自己要表达的内容,表现形式相对粗糙,没有行政区相关信息,只是一个个板块

1.4 进行行政区域地图可视化

如果要加上行政区边界信息,就可以把原来的地图底图进行替换掉,choroplethmapbox()函数可以帮助我们完成,具体的代码如下:

fig = go.Figure(go.Choroplethmapbox(geojson=china,locations=geo.Regions,z=geo.followerPercentage,
                                   colorscale='Cividis'
                                   ))
fig.update_layout(mapbox_style="carto-positron",mapbox_zoom=3,mapbox_center = {
    
    "lat" : 35.9 ,"lon" : 104.2})
fig.update_layout(margin={
    
    "t":0,"b":0,"l":0,"r":0})
fig

输出结果如下:(该函数中的z参数就是上一个函数中的color参数,用于指定颜色,还有一个colorscale就是指定颜色变化的色谱,保持颜色变化的和谐)
请添加图片描述
关于添加地图样式的设置:mapbox_style参数可以选择的赋值对象可以参考官网layout.mapbox.style,可能有的人网页如法访问,直接截图附在下面
在这里插入图片描述
明确一点指定mapbox_style后,执行程序,系统会自动向后台网址发生请求加载对应的样式,这中间会跟着网络有关系(如果没有挂vpn可能有些地图样式加载不出来)

  • 首先如果指定white-bg样式,就直接加载出来了,因为本来绘图的背景就是白色的,也就不用发送网络请求
  • 其次有一些自由使用的样式:open-street-map, carto-positron, carto-darkmatter, stamen-terrain, stamen-toner 或者 stamen-watercolor ,比如代码中使用的就是第二个样式
  • 最后就是有些必须通过token进行访问:basic, streets, outdoors, light, dark, satellite, 或者 satellite-streets

token可以通过mapbox官网注册后获取,注册成功后点击个人账户界面,然后点解Creata a token按钮,就会生成一个默认的公开的密匙
在这里插入图片描述
密匙的使用需要使用mapbox_accesstoken参数,比如将底层地图样式修改为basic,输出结果如下(这次的地图样式在放大后行政区就出现了)
请添加图片描述
剩下两个参数mapbox_zoom表示指定地图的缩放级别(margin参数之前已经介绍过,就是图框的上下左右的边缘值都设置为0时,图像最大),mapbox_center指定初始时地图的中心点(也就是程序运行后的第一眼地图按照哪个中心点展示),此外关于这个函数的使用也可以参看官网的使用示例,加深一下对这个函数的印象:Mapbox Choropleth Maps in Python

如果想要显示的内容是中文的内容,就需要把加载的地理信息文件中的省市部分的内容也修改为中文一模一样内容。为了展示这个功能,将原来的预分析的数据文件Beijing和Shanghai修改成为中文,然后原地理信息文件中只修改北京对应的信息
在这里插入图片描述
预分析数据和地理信息数据匹配时,地理信息数据中默认指定是id后对应的内容,要进行中文匹配修改的自然也就是id后的内容
在这里插入图片描述
重新读取数据并进行地图可视化,结果如下(此时北京由于地理信息文件中已经修改了,所以可以正常匹配成功,其他的省市还是英文,但是上海原数据中是中文,地理数据中还是英文,所以没有办法自动匹配成功,最后的图形中就没有显示这部分区域的内容)
请添加图片描述
如果想每个省市都是以中文进行显示,最后将所有的省市都替换一下即可

1.5 进行区域地图可视化

前面都是对于国家行政区域大面积数据的地图可视化,如果要进行某一具体省市或者区域地图可视化,就可以直接使用folium里面的绘图功能。绘图前需要明确一点,既然是具体到某一区域,就要指定具体生成图像后显示的位置,也就是中心点,比如要看一下洛杉矶的出租车的运营情况,首先要指定洛杉矶的位置,一般就是经纬度。

加载洛杉矶出租车营运的数据
在这里插入图片描述
查看数据量并取出前10条数据
在这里插入图片描述
接着就需要具体坐标点位置的确定,指定一下中心点坐标,可以使用前面folium中生成数据的地图中的标记点,操作如下
请添加图片描述
利用此方法获得洛杉矶的地址信息(也可以直接百度),然后显示洛杉矶地图

lat=37.77
long = -122.42

sanfran_map = folium.Map(location=[lat,long],zoom_start=12)
sanfran_map

输出结果如下:(zoom_start参数表示加载图片是时候是以几倍的视图视图显示,比如当赋值为1时就默认显示世界地图,随着数值增大,视图放大的倍数也大,区域信息显示越完整)
请添加图片描述
既然已经可以显示出区域的地图信息,那么就可以将分析的数据在地图中的显示出来,具体就是添加标记和标注

先进行标记的添加,代码指令: folium.CircleMarker()

sanfran_map = folium.Map(location=[lat,long],zoom_start=12)

incidents = folium.map.FeatureGroup()
for lat, lng, in zip(df_incidents.Y, df_incidents.X):
    incidents.add_child(
            folium.CircleMarker(
            [lat, lng],
            radius=5,
            color='red',
            fill=True,
            fill_color='blue',
            fill_opacity=0.6
            )
    )
sanfran_map.add_child(incidents)

输出结果如下:(整个过程就是先创建一个地图,指定显示的位置,接着创建一个群组放置标记,标记需要一个个添加,添加的依据就是经纬度数据,顺带着可以设置标记的样式,最终把群组添加到地图画像中完成绘制)
在这里插入图片描述
添加的标记没有交互的功能,只是显示在地图上,要实现交互的功能就需要添加文本的标注,代码指令:folium.Marker()

sanfran_map2 = folium.Map(location=[lat,long],zoom_start=12)
incidents = folium.map.FeatureGroup()
for lat, lng, in zip(df_incidents.Y, df_incidents.X):
    incidents.add_child(
            folium.CircleMarker(
            [lat, lng],
            radius=5,
            color='red',
            fill=True,
            fill_color='blue',
            fill_opacity=0.6 
            )
    )
    
lat1= list(df_incidents.Y)
long1  = list(df_incidents.X)
lables = list(df_incidents.Category)

for lat,long,lable in zip(lat1,long1,lables):
    folium.Marker([lat,long],popup=lable).add_to(sanfran_map2)

sanfran_map2.add_child(incidents)

在添加标记的基础上进行标注的添加,标注也是一个个的添加,依据经纬度,由于还要显示文本数据,所以对应的三个参数的循环,输出结果如下
请添加图片描述
如果要把全部的数据标记都放置在地图上会是什么效果,先不把十几万条数据放置在地图上,先放置3000个数据看看运行情况。结果中标记点密密麻麻,而且鼠标一滑动到这个显示区就会很卡顿,要是对这个地图进行缩小放大需要等待一会
在这里插入图片描述
如果是几十万的数据直接放置在上面就会是一个“灾难”,直接让系统崩溃,所以为了解决这个方式,可以将里面的数据点进行聚集,代码指令:MarkerCluster().add_to()

from folium.plugins import MarkerCluster

sanfran_map4 = folium.Map(location=[lat,long],zoom_start=12)
marker_cluster = MarkerCluster().add_to(sanfran_map4)

lat1= list(df_incidents.Y)
long1  = list(df_incidents.X)
lables = list(df_incidents.Category)

for lat,long,lable in zip(lat1,long1,lables):
    folium.Marker([lat,long],popup=lable).add_to(marker_cluster)

sanfran_map4

输出结果如下:(变化就仅在前三行,以及倒数第二行代码中添加到的对象换了,通过这种方式就能解决大样本数据标记显示的问题)
请添加图片描述

2 绘制动态数据图

加载相应的模块和测试数据,还是使用plotly中的内置数据
在这里插入图片描述

2.1 动态散点图

先回顾一下plotly.express模块绘制散点图的过程,假如要查看一下人均GDP和寿命之间的关系,颜色按照各大洲进行显示。由于数据值较大采用对数方式显示

px.scatter(df_cnt,x='gdpPercap',y='lifeExp',color='continent',log_x=True,hover_name='country')

输出结果为:
在这里插入图片描述
绘制动态散点图就是基于上图,使用核心参数animation_frame,代码如下

px.scatter(df_cnt,x='gdpPercap',y='lifeExp',
           color='continent',log_x=True,
           hover_name='country',animation_frame='year',
           range_x=[100,100000],
           range_y=[25,90],size_max=90,
           size='pop'
          )

输出结果为:(animation_frame参数就是指定绘制动画依据的字段,然后其它的一些参数,之前都已经讲解过)
请添加图片描述

2.2 绘制动态堆叠柱状图

绘制的原理和上面的图形一样,只是绘制的函数发生了变化,参数基本上没有变化

px.bar(df_cnt,x='continent',y='pop',
           color='continent',hover_name='country',
      animation_frame='year',range_y=[0,4000000000],
      )

输出结果为:(这里修改了绘图的字段)
请添加图片描述

2.3 绘制等值密度图

核心代码:px.density_contour()

fig = px.density_contour(df_cnt, x="gdpPercap", y="lifeExp", color="continent",marginal_y='histogram'
                         , animation_frame='year', range_y=[25,100])
fig         

输出结果为:
请添加图片描述

2.4 绘制动态热力图

核心代码:px.density_heatmap()

fig = px.density_heatmap(df_cnt, x="gdpPercap", y="lifeExp", marginal_y="histogram",
                        animation_frame='year', animation_group='country', range_y=[25,100])
fig.show()

输出结果为:
请添加图片描述

2.5 绘制动态地图

核心代码:px.choropleth()

px.choropleth(gapminder,               
              locations="iso_alpha",               
              color="lifeExp",
              hover_name="country",  
              animation_frame="year",    
              color_continuous_scale='solar',  
              height=600             
)

输出结果为:(关于color_continuous_scale参数的取值之前介绍过可以使用试错法,查看里面具体可以有哪些赋值对象)
请添加图片描述
随便给color_continuous_scale参数指定一个值,运行报错后会有提示
在这里插入图片描述

2.6 美国犯罪率的地图动态可视化

读取测试数据,去掉异常值
在这里插入图片描述
然后就是直接使用地图可视化的函数,结合这动态效果的参数animation_frame

px.choropleth(df, 
              locations = 'State_code',
              color="Murder_per100000", 
              animation_frame="Year",
              color_continuous_scale="oranges",
              locationmode='USA-states',
              scope="usa",
              range_color=(0, 20),
              title='Crime by State',
              height=600
             )

输出结果为:(里面的参数基本上都讲解过,有不理解的可以直接调用说明文档)
请添加图片描述

至此整个plotly的章节就介绍完毕,撒花✿✿ヽ(°▽°)ノ✿

Guess you like

Origin blog.csdn.net/lys_828/article/details/119491338