【plotly+ datashader+mapbox】Uber纽约上车点可视化/解决超大量地理数据可视化

前言

大部分时间我都是使用Pyecharts去做可视化,不过一直有个比较头疼的问题没法解决。

在pyecharts中是需要把所有的坐标点的数据加载到图表中,当数据量特别大的时候,那么这样一个图表可能会有好几百MB,使用起来会非常卡顿。虽然在Echarts中有ScatterGL来支持大数据量大可视化,不过在Pyecharts中没法直接支持,只能找一些曲线救国的方法,改善效果也不是很明显。

最近使用了一下plotly,发现了超大地理数据集可视化的解决办法,我们先来看下效果:

数据总共包含100W个数据点,地图缩放或者拖拽也不会存在卡顿。

其实这个解决办法也很好理解,datashader是将所有的数据点转换成为了包含所有点的一张图片,然后将这个图片与Plotly结合到一起,就相当于是在整个地图上加了一个图层,这样切换起来就不会卡顿了。

GIS图层这里是使用了Mapbox,Mapbox是一家非常优秀的地图厂商,各位可以去Mapbox定制属于自己的地图效果。

实现方法

接下来我们就详细说一下实现方法。

Mapbox图层

这个需要各位自己去Mapbox注册,免费的,注册完之后就可以定制自己的地图了。

定制完成后点击右上角的SHARE,复制出如下两个位置的数据就可以了!

 在plotly中使用Mapbox的代码

import plotly.express as px

# 自己去Mapbox申请一个Token
px.set_mapbox_access_token('pk.eyJ1IjoiYA....')

fig = px.scatter_mapbox(
    df,
    lat='Lat',
    lon='Lon',
    # 缩放比例
    zoom=12,
    # 地图中心位置
    center=dict(lat=40.74000520746974, lon=-73.97681683902668),
    mapbox_style="mapbox://styles/awesometang/cjb4fvg3o5m392tpjetxzaqgz"
)


fig.show()

datashader的使用

datashader的作用是将坐标点数据转换为像素密度栅格,栅格可以叠加在MapBox图层。

实现代码:

# 设置画布大小
cvs = ds.Canvas(plot_width=1980, plot_height=1000)
# 坐标点聚合
agg = cvs.points(dff, x='Lon', y='Lat')
coords_lat, coords_lon = agg.coords['Lat'].values, agg.coords['Lon'].values
# 四个角的坐标,用于在Mapbox中定位
coordinates = [[coords_lon[0], coords_lat[0]],
               [coords_lon[-1], coords_lat[0]],
               [coords_lon[-1], coords_lat[-1]],
               [coords_lon[0], coords_lat[-1]]]

# 生成的图层
img = tf.shade(agg, cmap=fire)[::-1].to_pil()

颜色这里我是使用了https://github.com/holoviz/colorcet中的配色方案fire。

 完整代码

将上面两部分和在一起,便完成了我们的图表了。

需要数据的可以自行去下载:

import pandas as pd 
import plotly.express as px
import datashader as ds
from colorcet import fire
import datashader.transfer_functions as tf


# 替换成你们自己的数据链接
df = pd.DataFrame()
df = df.append(pd.read_csv('/home/mw/input/uber5306/uber-pickups-in-new-york-city/uber-raw-data-apr14.csv'))
df = df.append(pd.read_csv('/home/mw/input/uber5306/uber-pickups-in-new-york-city/uber-raw-data-aug14.csv'))
df = df.append(pd.read_csv('/home/mw/input/uber5306/uber-pickups-in-new-york-city/uber-raw-data-jul14.csv'))
df = df.append(pd.read_csv('/home/mw/input/uber5306/uber-pickups-in-new-york-city/uber-raw-data-jun14.csv'))
df = df.append(pd.read_csv('/home/mw/input/uber5306/uber-pickups-in-new-york-city/uber-raw-data-may14.csv'))
df = df.append(pd.read_csv('/home/mw/input/uber5306/uber-pickups-in-new-york-city/uber-raw-data-sep14.csv'))


# 限制一下区域
# 有些离得很远的点,将整个画布范围拉的很大
# 最后会导致数据点都集中在很小一块
dff = df.query('Lat < 40.82').query('Lat > 40.70').query('Lon > -74.07').query('Lon < -73.86')
# 设置画布大小
cvs = ds.Canvas(plot_width=1980, plot_height=1000)
# 坐标点聚合
agg = cvs.points(dff, x='Lon', y='Lat')
coords_lat, coords_lon = agg.coords['Lat'].values, agg.coords['Lon'].values
# 四个角的坐标,用于在Mapbox中定位
coordinates = [[coords_lon[0], coords_lat[0]],
               [coords_lon[-1], coords_lat[0]],
               [coords_lon[-1], coords_lat[-1]],
               [coords_lon[0], coords_lat[-1]]]

# 生成的图层
img = tf.shade(agg, cmap=fire)[::-1].to_pil()

# 自己去申请一个Token
px.set_mapbox_access_token('pk.eyJ1Ijo')

fig = px.scatter_mapbox(
    dff[:1],
    lat='Lat',
    lon='Lon',
    zoom=12,
    center=dict(lat=40.74000520746974, lon=-73.97681683902668),
    height=800)

fig.update_layout(mapbox_style="mapbox://styles/awesometang/cjb4fvg3o5m392tpjetxzaqgz",
                  mapbox_layers=[
                      {
                          "sourcetype": "image",
                          "source": img,
                          "coordinates": coordinates
                      }],
                    title='Uber Pickups In New-York'
                  )
fig.show()
# 保存图片
pio.write_image(fig, 'Uber Pickups In New-York.png', width=1980,height=1000)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AwesomeTang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值