matplotlib自定义colorbar-分段与线性色标

notebook地址jupyter viewGithub地址

准备数据

准备数据用以描述颜色分布。

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

midwest数据集,预览该数据集并初步可视化:

midwest = pd.read_csv('../../data/midwest_filter.csv')
midwest.head(10)
PIDcountystateareapoptotalpopdensitypopwhitepopblackpopamerindianpopasian...percprofpoppovertyknownpercpovertyknownpercbelowpovertypercchildbelowpovertpercadultpovertypercelderlypovertyinmetrocategorydot_size
0561ADAMSIL0.052660901270.96154063917170298249...4.3558596362896.27477713.15144318.01171711.00977612.4438120AAR250.944411
1562ALEXANDERIL0.01410626759.000000705434961948...2.8703151052999.08714532.24427845.82651427.38564725.2289760LHR185.781260
2563BONDIL0.02214991681.409091144774293516...4.4885721423594.95697412.06884414.03606110.85209012.6974100AAR175.905385
3564BOONEIL0.017308061812.1176502934412746150...4.1978003033798.4775697.20901911.1795365.5360136.2170471ALU319.823487
4565BROWNIL0.0185836324.2222225264547145...3.367680481582.50514013.52024913.02288911.14321119.2000000AAR130.442161
5566BUREAUIL0.05035688713.760000351575065195...3.2758913510798.37200210.39963514.1588198.17928711.0085860AAR180.023052
6567CALHOUNIL0.0175322313.05882452981815...3.209601524198.47801615.14978113.78776112.93233121.0852710LAR129.021269
7568CARROLLIL0.02716805622.407407165191113061...3.0557271645597.91728711.71072617.22546210.0270379.5250520AAR168.395572
8569CASSIL0.02413437559.8750001338416823...3.2067991308197.35059913.87508617.99478411.91434313.6601800AAR160.436363
9571CHRISTIANIL0.04234418819.47619034176825189...3.0899983378898.16956211.70829916.3206129.56970011.4906410AAR193.478750

10 rows × 29 columns

气泡图使用标签颜色

# 将分类category数据作为颜色标记
categories = midwest['category'].unique()
colors = [plt.cm.tab10(i/float(len(categories)-1)) for i in range(len(categories))]
# 设计绘图尺寸等细节
fig, ax = plt.subplots(1, 1, figsize=(16, 10), dpi=80)
# 绘制不同分类(category)的气泡图,气泡尺寸取决于dot_size属性
for i, category in enumerate(categories):
    data = midwest.loc[midwest['category']==category, :]
    ax.scatter('area', 'poptotal', s='dot_size', data=data, 
                c=[colors[i]]*len(data), edgecolors='black', linewidths=.5, label=category)
ax.set_xlabel('Area', fontsize=14)
ax.set_ylabel('Poptotal', fontsize=14)
ax.set_title('Bubble Plot', loc='left', fontsize=16)
ax.legend(fontsize=12, labelspacing=0.8, borderpad=.7)
plt.show()

在这里插入图片描述

实现将AreaPoptotal数据作为x、y轴信息,dot_size作为气泡尺寸信息,category作为气泡颜色信息。我们思考一个问题,如果气泡颜色展示的不是标签化的而是连续数值的信息我们的颜色对应colorbar应该如何制作:

分段colorbar-气泡图

假设我们将percprof字段信息作为colorbar的对应信息,并设置颜色分段:

midwest['percprof'].describe()
count    332.000000
mean       3.842269
std        1.647157
min        0.520291
25%        2.870991
50%        3.400538
75%        4.318381
max       14.089892
Name: percprof, dtype: float64

根据数据描述信息,我们可以考虑0-15数值分段描述:

from matplotlib.colors import ListedColormap, BoundaryNorm
fig, ax = plt.subplots(1, 1, figsize=(20, 10), dpi=80)
bounds = [0, 2.88, 3.5, 4.5, 12, 15]
colors = ['#7FCAB2', '#EA9F7B', '#9FAED2', '#E99CCB', '#ADD696']
cmap = ListedColormap(colors)
norms = BoundaryNorm(bounds, cmap.N)
fc = ax.scatter('area', 'poptotal', s='dot_size', data=midwest, c='percprof', 
                cmap=cmap, norm=norms, vmin=0, vmax=15,
                edgecolors='black', linewidths=.5)
ax.set_xlabel('Area', fontsize=14)
ax.set_ylabel('Poptotal', fontsize=14)
ax.set_title('Bubble Plot', loc='left', fontsize=16)
cb = plt.colorbar(fc, ax=ax)
cb.set_label('percprof', fontsize=16)
plt.show()

在这里插入图片描述

可以看到我们分布数值不是线性的,是基于百分位数绘制颜色的,假设我们需要colorbar上颜色标尺满足线性可以如下设置 spacing{'uniform', 'proportional'}

fig, ax = plt.subplots(1, 1, figsize=(20, 10), dpi=80)
bounds = [0, 2.88, 3.5, 4.5, 12, 15]
colors = ['#7FCAB2', '#EA9F7B', '#9FAED2', '#E99CCB', '#ADD696']
cmap = ListedColormap(colors)
norms = BoundaryNorm(bounds, cmap.N)
fc = ax.scatter('area', 'poptotal', s='dot_size', data=midwest, c='percprof', 
                cmap=cmap, norm=norms, vmin=0, vmax=15,
                edgecolors='black', linewidths=.5)
ax.set_xlabel('Area', fontsize=14)
ax.set_ylabel('Poptotal', fontsize=14)
ax.set_title('Bubble Plot', loc='left', fontsize=16)
cb = plt.colorbar(fc, ax=ax, spacing='proportional')
cb.set_label('percprof', fontsize=16)
plt.show()

在这里插入图片描述

连续colorbar-气泡图

from matplotlib.colors import LinearSegmentedColormap
fig, ax = plt.subplots(1, 1, figsize=(20, 10), dpi=80)
bounds = [0, 2.88, 3.5, 4.5, 12, 15]
# 由于colormap的值必须在0-1之间所以做了线性分布处理
nodes = [(v-0)/15 for v in bounds]
colors = ['#7FCAB2', '#EA9F7B', '#9FAED2', '#E99CCB', '#ADD696', '#E6CCA4']
cmap = LinearSegmentedColormap.from_list('mymap', list(zip(nodes, colors)))
fc = ax.scatter('area', 'poptotal', s='dot_size', data=midwest, c='percprof', 
                cmap=cmap, vmin=0, vmax=15,
                edgecolors='black', linewidths=.5)
ax.set_xlabel('Area', fontsize=14)
ax.set_ylabel('Poptotal', fontsize=14)
ax.set_title('Bubble Plot', loc='left', fontsize=16)
cb = plt.colorbar(fc, ax=ax)
cb.set_label('percprof', fontsize=16)
plt.show()

在这里插入图片描述

上面演示半分位分布的颜色映射,下面我们挑选颜色渐进,按照线性分布(不按百分位数分布),重新绘制下:

fig, ax = plt.subplots(1, 1, figsize=(20, 10), dpi=80)
# 采样简单的colormap线性映射关系
colors = ['#024CEB', '#02BBA9', '#65FF00', '#FEFF00', '#FF8800', '#D40608']
cmap = LinearSegmentedColormap.from_list('mymap', colors)
fc = ax.scatter('area', 'poptotal', s='dot_size', data=midwest, c='percprof', 
                cmap=cmap, vmin=0, vmax=15,
                edgecolors='black', linewidths=.5)
ax.set_xlabel('Area', fontsize=14)
ax.set_ylabel('Poptotal', fontsize=14)
ax.set_title('Bubble Plot', loc='left', fontsize=16)
cb = plt.colorbar(fc, ax=ax)
cb.set_label('percprof', fontsize=16)
plt.show()

在这里插入图片描述

可以看到主要颜色在4以下,线性和百分位分段需要自己取舍!

  • 8
    点赞
  • 48
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值