社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

怎么用 Python 绘制这样的图?

算法爱好者 • 2 年前 • 239 次点击  

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

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


1. 什么是弦图

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

来源:网络

对于弦图,有以下特点:

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

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

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

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


2. 弦图绘制

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

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

pip install holoviews

我们先看看官方案例




    
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 数据准备

用以下数据进行案例演示

import pandas as pd

df = pd.read_clipboard()
df
姓名王者曙光吃鸡原神金铲铲扎金花
小明20015101217
才哥11 180115
小华10914284
小青18412368
小天179134126

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

data = df.melt(id_vars=['姓名'], 
               value_vars=['王者''曙光''吃鸡''原神''金铲铲''扎金花']
              )
data.head()

姓名variablevalue
0小明王者20
1才哥王者11
2小华王者10
3小青王者18
4小天王者17

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

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

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

node = pd.DataFrame(data['姓名'].append(data['variable']).unique(),
                    columns=['节点']
                   )
node

节点
0小明
1才哥
2小华
3小青
4小天
5王者
6曙光
7吃鸡
8原神
9金铲铲
10扎金花

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

nodes = hv.Dataset(node, '节点',)

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

2.2 绘制操作

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文件

hv.save(busiest_airports,r'output.html')
保存本地

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

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


- EOF -

推荐阅读  点击标题可跳转

1、最好用的 Python 虚拟环境,没有之一

2、20 条非常实用的 Python 代码,建议收藏!

3、Python 里最具代表性的符号,竟如此强大


觉得本文有帮助?请分享给更多人

推荐关注「算法爱好者」,修炼编程内功

点赞和在看就是最大的支持❤️

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/121367
 
239 次点击