前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >怎么用Python绘制这样的图?

怎么用Python绘制这样的图?

作者头像
可以叫我才哥
发布2021-09-03 14:08:23
1.1K0
发布2021-09-03 14:08:23
举报
文章被收录于专栏:可以叫我才哥可以叫我才哥

大家好,我是才哥。

最近看到一张图,感觉很酷炫,搜索得知是叫做弦图。看到很多用R语言绘制的案例,以及有Excel大佬用VBA也绘制了一个,简直不要太强。

那么,Python可以绘制吗?找了一圈发现有一个付费的第三方包可以实现,因为需要付费,这里就不介绍了。最终,可算让我找到了Python绘制的免费方案,今天我们就一起来看看吧!

1. 什么是弦图

下面这张图就是弦图,主要用于展示多个对象之间的关系,连接在圆上任意两点之间的线段叫做弦。

来源:网络

对于弦图,有以下特点:

  • 用不同颜色区分不同的对象(点)
  • 圆上的两点之间的弦表示之间存在关系
  • 弦的宽度表示关系程度,关系越明显则弦宽越宽
  • 因为不同对象颜色不同,可以通过两点之间弦的颜色区分是对象->对象的方向

一般来说,弦图可以用于以下几种场景:

  • 人口迁徙(不同城市之间迁入迁出)
  • 电竞战队或球队之间选手交易
  • 具有重叠成分的不同成品与各成分关系
  • 类似以上几类场景的情况等等

今天,我们绘制弦图要用到的可视化库是holoviews

2. 弦图绘制

HoloViews是一个开源的Python库,可以用非常少的代码行中完成数据分析和可视化,除了默认的matplotlib后端外,还添加了一个Bokeh后端。Bokeh提供了一个强大的平台,通过结合Bokeh提供的交互式小部件,可以使用HTML5 canvas和WebGL快速生成交互性和高维可视化,非常适合于数据的交互式探索。官网:http://holoviews.org/

首先,我们需要安装第三方库holoviews

代码语言:javascript
复制
pip install holoviews

我们先看看官方案例

代码语言:javascript
复制
import holoviews as hv
from holoviews import opts, dim
from bokeh.sampledata.airport_routes import routes, airports

# 选择bokeh引擎
hv.extension('bokeh')

# Count the routes between Airports
route_counts = routes.groupby(['SourceID', 'DestinationID']).Stops.count().reset_index()
nodes = hv.Dataset(airports, 'AirportID','City')
chord = hv.Chord((route_counts, nodes), ['SourceID', 'DestinationID'], ['Stops'])

# Select the 6 busiest airports
busiest = list(routes.groupby('SourceID').count().sort_values('Stops').iloc[-6:].index.values)
busiest_airports = chord.select(AirportID=busiest, selection_mode='nodes')

busiest_airports.opts(
    opts.Chord(cmap='Category20', edge_color=dim('SourceID').str(), 
               height=500,
               labels='City', 
               node_color=dim('AirportID').str(), width=500))

弦图

我们拿玩家在不同游戏中的付费金额来绘制弦图,演示每一个步骤

2.1 数据准备

用以下数据进行案例演示

代码语言:javascript
复制
import pandas as pd

df = pd.read_clipboard()
df

姓名

王者

曙光

吃鸡

原神

金铲铲

扎金花

小明

20

0

15

10

12

17

才哥

11

1

8

0

11

5

小华

10

9

14

2

8

4

小青

18

4

12

3

6

8

小天

17

9

13

4

12

6

我们需要将宽表变为窄表(如果你就是窄表,则不需要这么操作)

代码语言:javascript
复制
data = df.melt(id_vars=['姓名'], 
               value_vars=['王者', '曙光', '吃鸡', '原神', '金铲铲', '扎金花']
              )
data.head()

姓名

variable

value

0

小明

王者

20

1

才哥

王者

11

2

小华

王者

10

3

小青

王者

18

4

小天

王者

17

用于绘制弦的数据已经有了:

  • 弦的方向就是姓名->variable
  • 弦的宽度就是value

接下来,我们搞定 圆上的对象(点)

代码语言:javascript
复制
node = pd.DataFrame(data['姓名'].append(data['variable']).unique(),
                    columns=['节点']
                   )
node

节点

0

小明

1

才哥

2

小华

3

小青

4

小天

5

王者

6

曙光

7

吃鸡

8

原神

9

金铲铲

10

扎金花

最终,对象节点数据如下:

代码语言:javascript
复制
nodes = hv.Dataset(node, '节点',)

搞定这些,我们就可以进行绘制了

2.2 绘制操作

代码语言:javascript
复制
chord = hv.Chord((route_counts, nodes), 
                 ['姓名', 'variable'], ['value'])

# 可选择节点数
busiest = node['节点'].to_list()
busiest_airports = chord.select(AirportID=busiest, selection_mode='nodes')

busiest_airports.opts(
    opts.Chord(cmap='Tab20', edge_color=dim('姓名').str(), 
               height=500,
               width=500,
               labels='节点',
               node_color='节点',
               edge_visible=True
              ))

最终,我们得到效果如下:

弦图案例

这个弦图是可以交互的,可以save本地html文件

代码语言:javascript
复制
hv.save(busiest_airports,r'output.html')

保存本地

其实,弦图绘制还有很多参数,大家可以自己help试试(比如背景颜色、字体大小、弦的颜色cmap等等)

以上就是本次全部内容,相信大家也可以做出酷炫的弦图了!

加油~

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-08-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 可以叫我才哥 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 2.1 数据准备
  • 2.2 绘制操作
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档