​用Python把图做的好看点:用Matplotlib画个好看的气泡图

[复制链接]
# b4 x7 |0 ^ t A! S) }) h

我们继续来把简单的图形丢到极坐标,这次是气泡图和柱状图,临摹的对象是澎湃美数课

0 G. U' c: b. O0 R4 `/ Z1 r3 l
- N+ O% B) u' m

这个图看起来很好看,原理其实很简单,把柱状图和气泡图从笛卡尔坐标系中转移到极坐标系中来就OK

$ T x9 T" a7 C' J; D; e3 U x

我们开始本次的临摹吧

' E# W* \3 B) k7 O

本期的主题如下:

熟悉一下柱状图的一些参数熟悉一下散点图的一些参数熟悉一下极坐标系的规则(高中内容啦)熟悉一下这么自定义字体熟悉一下网格线

我们先来说说及极坐标内,一个点位置该怎么表示:(笔者很懒惰,就直接从网上复制图片来教学了)

i$ R( I' j7 i& b4 W) [: m
x4 @) s$ ~ v8 r9 Z

从图上可以看出来,x轴为那个带箭头的线,matplotlib中也一样,极坐标的起点在同样的位置,不过在matplotlib里 x表示的是角度,y表示的长度,所以确定好夹角θ,和半径长度就OK

0 r5 |% \" A3 a; ^

我们在看看 美术课里这个样图,一排上,一共有15个圆,且最后一个和第一个没有在90°与270°的位置上,所以我们要把圆分成36份,也就是每份是2π/36

0 e/ b+ H4 D' ~5 C7 P

这样我们就可以确定等差数列了,我们以3/2π为起点,不断加2π/36

3 A) o3 L7 I- w y* I

我们来画第一圈圆

+ v$ o( T3 H& q4 u
import numpy as np; R) g5 @. ?. H8 x% t# X/ k4 x k: [ import matplotlib.pyplot as plt* |% j! I% l3 K/ n 9 }( x% M3 D) \2 [6 I! u' R" A! \9 o y1 `$ p S1=np.array([2572,2483,2302,2125,1990,1853,1694,1400,1134,982,869,776,668,584,480])*2 ' e# k& U* S9 F, }) ^- _7 Y* N #为了把图做大一点,把圆扩大了一倍# G1 i& t: k9 z x1=[(3/2)*np.pi+np.pi/(len(S1)+1)*(i+1) for i in range(2*(len(S1)+1)) if i<len(S1)]4 m" e6 C U* I5 e # len(S1)+1 等于16 , 因为python里计数从0开始,所以i+1起始加一, : W% X$ _& j1 o7 v5 o # 又因为我们只有15个圆,所以我们生成的位置Y也只要十五个,所以加入限制条件<15 5 U4 @. h! n6 t+ h% y, [ $ H2 b. l! K: q8 P- a y1=[180 for i in range(2*(len(S1)+1)) if i<len(S1) ] 8 b4 K5 ?$ P/ I$ o1 \ # 我们继续生成15个y值,这样一来,我们三个参数都确定了,气泡了x轴位置,y轴位置,以及气泡大小. J: v9 C- w5 g1 C0 L/ }1 t$ \0 N # 下面开始画图 , M$ Y2 i: X! V% Y$ D# o$ v9 R0 S& ~0 o; C$ q fig=plt.figure(figsize=(13.44*2,7.5*2),facecolor=w)#建立一个画布 / W. R3 r4 i6 R# I3 G7 M8 L0 P P ax = fig.add_subplot(111,projection=polar,facecolor=w)#建立一个坐标系,projection=polar表示极坐标 5 } x* |: p0 R ax.scatter(x=x1,y=y1,s=S1,color=(180/255,204/255,30/255),alpha=0.5,linewidths=0) #不要气泡有边框线,我们把linewidth设置为0 4 V1 ~# t2 L- h' q; c* O plt.ylim(0,220) #限制y轴的显示大小- o; X; d B6 S$ y+ ?% x9 H 4 O4 G, @4 a7 M- c# i y 8 ^( M( b( [" m1 N1 S9 R; S 散点图的参数 & Z- ^: V# X. e; Z% q1 q 1. xy表示点位置s表示点的大小 4 q: J- N% k7 G# f6 l+ R! A- H% E+ R1 K 2. color表示颜色可以传入一个元组对RGB值归一 9 x1 U' d7 x) s' x: v; v& L# h 3. alpha表示的是透明度) \) _6 I2 k. s, `2 [# F5 k . ~. B4 ]/ J4 @' _1 K+ s1 K
6 I+ L% y1 C- {: o
第一圈圆
S2=np.array([2028,1976,1962,1925,1904,1833,1730,1577,1524,1493,1475,1589,1511,1505,1524])*27 e2 {9 I" Y4 ~8 R x2=[(0)*np.pi+np.pi/(len(S1)+1)*(i+1) for i in range(2*(len(S1)+1))] 5 B9 A! Y; M7 D- _" y, |/ } y2=[130 for i in range(2*(len(S1)+1)) if i<len(S1) ]
0 Y+ S+ R9 m# n: }. }- {

我们用同样的方式计算出第二圈圆的位置,画出来

& P2 o$ o# s* p+ v5 {5 i9 }1 Y
1 x4 i* p1 k' b' O$ s# e, R2 [4 O9 E" Y

接着我们把柱状图也丢进极坐标掰弯

) b J- s& \# _$ ^
柱状图可以用四个参数来确定每个柱子的位置 # Q' F9 e& F5 k7 ` " ^3 y- l8 Y; t, |+ L+ D& r H1=[56,55,54,52,51,50,49,47,43,40,37,34,31,28,24]& c0 A4 d# _2 M/ L% q$ r- A W1=[0.05 for i in range(2*(len(S1)+1)) if i<len(S1)]- X2 \: \1 M: q% I+ [& f0 F" l B=[30 for i in range(2*(len(S1)+1)) if i<len(S1)]; q* o# F, Z# i3 t 6 l' P% {* P. j/ d& K% n. \ ax.bar(x=x1, height=H1, width=W1,bottom=B,color=(255/255,171/255,1/255))1 B4 P; c+ c) I- S2 @" d4 D& f$ l4 }7 E ) ]( n, i% v5 K" S x表示x轴的位置, 1 j0 Z" [, ~1 {& @* V; h2 ?7 G bottom表示柱子最底端的位置 * w, l: i5 V/ p& I1 A- @% L2 M& c6 ` height表示 柱子的长度6 `3 v2 w/ R1 F+ k d; X3 O width表示柱子的宽度 2 E( }4 }: c; n( F& R" q6 J
% Z$ o3 d! y! \: N- Z2 M
0 K7 u( z9 Q+ g/ N- ~

最后我们把 坐标上的线,还有坐标轴上的文字去掉,以及背后画个网格线,

6 T F& `1 t0 { P* R" F1 h

ax.spines[polar].set_visible(False) #去掉坐标轴的为外面一层 粗的线

; _) f: v5 l: q4 \

plt.grid(color=gray, linestyle=:, linewidth=1,which=major,axis=x,alpha=0.1) #添加网格线

3 y) A9 g/ |3 r# u! {

ax.set_yticks([]) #去掉 y轴上的文字

1 _6 P$ j5 P; {5 ?* d* A

ax.set_xticks(x2) # 应为网格线是跟着x轴走的,如果去掉x轴的话,网格线也就没了

ax.tick_params(axis=x,labelsize=0) #因为我们保留了x轴,x轴上的文字会存在,所以把x轴上的文字大小设置为0 * I+ T4 r1 w' s) ^
) u2 y9 q# q- N$ }4 \

最后我们选择喜欢的字体,然后打上数据标签,并保存

& [1 U) ?6 X; L7 k0 K) {
import matplotlib.font_manager# f, R% P0 y' Y5 V- u o font=matplotlib.font_manager.FontProperties(fname=D:\\Fonts\\English\\Museo700-Regular.otf)3 G/ k8 n- i9 G7 V9 E2 I6 r7 H, G ) D) D. A( p% {6 U: ` for i in range(len(x1)): # ?( r. C/ e6 J, w* [. w3 w. u0 ~ ax.text(x=x1[i],y=y1[i],s=S1[i],color=gray,ha=center, va= center,fontsize=12,fontproperties=font)/ b0 [: F! D Y7 G: j1 M! ~8 j for i in range(len(x1)):9 z* W6 T1 j" i: y7 v) N5 O ax.text(x=x1[i],y=y2[i],s=S2[i],color=gray,ha=center, va= center,fontsize=12,fontproperties=font)0 b% l$ }8 s( l for i in range(len(x1)): " B) T3 Y- u; |/ |* b- y# y7 F; |5 a ax.text(x=x1[i],y=H1[i]+40,s="{}%".format(H1[i]) ,color=gray,ha=center, va= center,fontsize=12,fontproperties=font)& }# n( T) o& N0 j8 {8 C# I B- Z' g" M7 P. ^0 {* f fig.savefig(D:\\test.png,dpi=400,bbox_inches=tight,transparent=False)
0 G* e4 _. E1 q+ X$ w7 p) S$ x

裁掉不要的部分

- B0 C/ i0 {, \$ `! v; @5 d
! N5 s ]% \) }( k5 U) ]

笔者比较懒惰,就在搞那些文字与标题啦,如果要加文字与标题的话可以保存eps格式的矢量图文件,放在AI里进行深度的加工和处理哦

. H' B9 t$ h+ [* s9 \

就这样 完结 撒花✿✿ヽ(°▽°)ノ✿

2 d0 i. ^8 _0 e5 |5 K

基础的部分可以看看这个文章:

4 E7 [# v- r' {0 D" Q. C 1 y* N: {, q, s$ W8 a, Y- r

其他在极坐标里的画图可以看看这个

" P: S9 T G& c0 c. j ; y1 D$ j" s7 Z 1 W8 Y' |- }# L4 p' ^% q5 F- ]1 W% _ + R4 A1 v7 p. T, {% \9 |+ G/ W: I , I' |9 M7 E" D1 L$ _ V& k: | 6 u+ p+ ^, S1 t& P X: a0 ?/ T1 ?# N, z( S% V- ? 8 e, T- Z0 U. ?" \
回复

举报 使用道具

相关帖子

全部回帖
暂无回帖,快来参与回复吧
懒得打字?点击右侧快捷回复 【吾爱海洋论坛发文有奖】
您需要登录后才可以回帖 登录 | 立即注册
编织自己的梦想
活跃在2025-1-26
快速回复 返回顶部 返回列表