跳到主要内容
40 个 Python 可视化图表案例及代码实现 | 极客日志
Python AI 算法
40 个 Python 可视化图表案例及代码实现 40 种常用的 Python 数据可视化图表案例,涵盖分布、关系、排行、局部整体、时间序列、地理空间和流程七大类。内容包含 Seaborn、Matplotlib、Plotly、Folium 等主流库的代码实现,如小提琴图、核密度估计、热力图、散点图、雷达图、词云、地图、桑基图等。每个案例提供具体代码示例和效果说明,适合数据分析师和开发者快速查阅参考。
锁机制 发布于 2025/2/6 更新于 2026/6/1 19 浏览前言
数据可视化是数据科学中关键的一步。在以图形方式表现某些数据时,Python 能够提供很大的帮助。
不过有些小伙伴也会遇到不少问题,比如选择何种图表,以及如何制作,代码如何编写,这些都是问题!
今天给大家介绍一个 Python 图表大全,40 个种类,总计约 400 个示例图表。
分为 7 个大系列:分布、关系、排行、局部整体、时间序列、地理空间、流程。
文档地址:https://www.python-graph-gallery.com
GitHub 地址:https://github.com/holtzy/The-Python-Graph-Gallery
给大家提供了示例及代码,几分钟内就能构建一个你所需要的图表。
下面就给大家介绍一下~
01. 小提琴图
小提琴图可以将一组或多组数据的数值变量分布可视化。
相比有时会隐藏数据特征的箱形图相比,小提琴图值得更多关注。
import seaborn as sns
import matplotlib.pyplot as plt
df = sns.load_dataset('iris' , data_home='seaborn-data' , cache=True )
sns.violinplot(x=df["species" ], y=df["sepal_length" ])
plt.show()
使用 Seaborn 的 violinplot() 进行绘制,结果如下。
02. 核密度估计图
核密度估计图其实是对直方图的一个自然拓展。
可以可视化一个或多个组的数值变量的分布,非常适合大型数据集。
import seaborn as sns
import matplotlib.pyplot as plt
df = sns.load_dataset('iris' , data_home='seaborn-data' , cache=True )
sns.kdeplot(df[ ])
plt.show()
'sepal_width'
使用 Seaborn 的 kdeplot() 进行绘制,结果如下。
03. 直方图 import seaborn as sns
import matplotlib.pyplot as plt
df = sns.load_dataset('iris' , data_home='seaborn-data' , cache=True )
sns.histplot(a=df["sepal_length" ], kde=False , rug=False )
plt.show()
使用 Seaborn 的 histplot() 进行绘制,结果如下。
04. 箱形图 可以快速获得中位数、四分位数和异常值,但也隐藏数据集的各个数据点。
import seaborn as sns
import matplotlib.pyplot as plt
df = sns.load_dataset('iris' , data_home='seaborn-data' , cache=True )
sns.boxplot(x=df["species" ], y=df["sepal_length" ])
plt.show()
使用 Seaborn 的 boxplot() 进行绘制,结果如下。
05. 山脊线图 每个组都表示为一个密度图,每个密度图相互重叠以更有效地利用空间。
import plotly.graph_objects as go
import numpy as np
import pandas as pd
temp = pd.read_csv('2016-weather-data-seattle.csv' )
temp['year' ] = pd.to_datetime(temp['Date' ]).dt.year
year_list = [1950 , 1960 , 1970 , 1980 , 1990 , 2000 , 2010 ]
temp = temp[temp['year' ].isin(year_list)]
temp = temp.groupby(['year' , 'Mean_TemperatureC' ]).agg({'Mean_TemperatureC' : 'count' }).rename(columns={'Mean_TemperatureC' : 'count' }).reset_index()
array_dict = {}
for year in year_list:
array_dict[f'x_{year} ' ] = temp[temp['year' ] == year]['Mean_TemperatureC' ]
array_dict[f'y_{year} ' ] = temp[temp['year' ] == year]['count' ]
array_dict[f'y_{year} ' ] = (array_dict[f'y_{year} ' ] - array_dict[f'y_{year} ' ].min ()) / (array_dict[f'y_{year} ' ].max () - array_dict[f'y_{year} ' ].min ())
fig = go.Figure()
for index, year in enumerate (year_list):
fig.add_trace(go.Scatter(
x=[-20 , 40 ], y=np.full(2 , len (year_list) - index),
mode='lines' ,
line_color='white' ))
fig.add_trace(go.Scatter(
x=array_dict[f'x_{year} ' ],
y=array_dict[f'y_{year} ' ] + (len (year_list) - index) + 0.4 ,
fill='tonexty' ,
name=f'{year} ' ))
fig.add_annotation(
x=-20 ,
y=len (year_list) - index,
text=f'{year} ' ,
showarrow=False ,
yshift=10 )
fig.update_layout(
title='西雅图平均温度' ,
showlegend=False ,
xaxis=dict (),
yaxis=dict (showticklabels=False )
)
fig.show()
Seaborn 没有专门的函数来绘制山脊线图,可以多次调用 kdeplot() 来制作。
06. 散点图 import seaborn as sns
import matplotlib.pyplot as plt
df = sns.load_dataset('iris' , data_home='seaborn-data' , cache=True )
sns.regplot(x=df["sepal_length" ], y=df["sepal_width" ])
plt.show()
使用 Seaborn 的 regplot() 进行绘制,结果如下。
07. 矩形热力图 矩形热力图,矩阵中的每个值都被表示为一个颜色数据。
import seaborn as sns
import pandas as pd
import numpy as np
df = pd.DataFrame(np.random.random((5 ,5 )), columns=["a" ,"b" ,"c" ,"d" ,"e" ])
p1 = sns.heatmap(df)
使用 Seaborn 的 heatmap() 进行绘制,结果如下。
08. 相关性图 相关性图或相关矩阵图,分析每对数据变量之间的关系。
相关性可视化为散点图,对角线用直方图或密度图表示每个变量的分布。
import seaborn as sns
import matplotlib.pyplot as plt
df = sns.load_dataset('iris' , data_home='seaborn-data' , cache=True )
sns.pairplot(df)
plt.show()
使用 Seaborn 的 pairplot() 进行绘制,结果如下。
09. 气泡图 气泡图其实就是一个散点图,其中圆圈大小被映射到第三数值变量的值。
import matplotlib.pyplot as plt
import seaborn as sns
from gapminder import gapminder
data = gapminder.loc[gapminder.year == 2007 ]
sns.scatterplot(data=data, x="gdpPercap" , y="lifeExp" , size="pop" , legend=False , sizes=(20 , 2000 ))
plt.show()
使用 Seaborn 的 scatterplot() 进行绘制,结果如下。
10. 连接散点图 连接散点图就是一个线图,其中每个数据点由圆形或任何类型的标记展示。
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
df = pd.DataFrame({'x_axis' : range (1 , 10 ), 'y_axis' : np.random.randn(9 ) * 80 + range (1 , 10 )})
plt.plot('x_axis' , 'y_axis' , data=df, linestyle='-' , marker='o' )
plt.show()
使用 Matplotlib 的 plot() 进行绘制,结果如下。
11. 二维密度图 二维密度图或二维直方图,可视化两个定量变量的组合分布。
它们总是在 X 轴上表示一个变量,另一个在 Y 轴上,就像散点图。
然后计算二维空间特定区域内的次数,并用颜色渐变表示。
形状变化:六边形 hexbin chart,正方形 2d histogram,核密度 2d density plots 或 contour plots。
import numpy as np
import matplotlib.pyplot as plt
from scipy.stats import kde
data = np.random.multivariate_normal([0 , 0 ], [[1 , 0.5 ], [0.5 , 3 ]], 200 )
x, y = data.T
fig, axes = plt.subplots(ncols=6 , nrows=1 , figsize=(21 , 5 ))
axes[0 ].set_title('Scatterplot' )
axes[0 ].plot(x, y, 'ko' )
nbins = 20
axes[1 ].set_title('Hexbin' )
axes[1 ].hexbin(x, y, gridsize=nbins, cmap=plt.cm.BuGn_r)
axes[2 ].set_title('2D Histogram' )
axes[2 ].hist2d(x, y, bins=nbins, cmap=plt.cm.BuGn_r)
k = kde.gaussian_kde(data.T)
xi, yi = np.mgrid[x.min ():x.max ():nbins * 1j , y.min ():y.max ():nbins * 1j ]
zi = k(np.vstack([xi.flatten(), yi.flatten()]))
axes[3 ].set_title('Calculate Gaussian KDE' )
axes[3 ].pcolormesh(xi, yi, zi.reshape(xi.shape), shading='auto' , cmap=plt.cm.BuGn_r)
axes[4 ].set_title('2D Density with shading' )
axes[4 ].pcolormesh(xi, yi, zi.reshape(xi.shape), shading='gouraud' , cmap=plt.cm.BuGn_r)
axes[5 ].set_title('Contour' )
axes[5 ].pcolormesh(xi, yi, zi.reshape(xi.shape), shading='gouraud' , cmap=plt.cm.BuGn_r)
axes[5 ].contour(xi, yi, zi.reshape(xi.shape))
plt.show()
使用 Matplotlib 和 scipy 进行绘制,结果如下。
12. 条形图 条形图表示多个明确的变量的数值关系。每个变量都为一个条形。条形的大小代表其数值。
import numpy as np
import matplotlib.pyplot as plt
height = [3 , 12 , 5 , 18 , 45 ]
bars = ('A' , 'B' , 'C' , 'D' , 'E' )
y_pos = np.arange(len (bars))
plt.bar(y_pos, height)
plt.xticks(y_pos, bars)
plt.show()
使用 Matplotlib 的 bar() 进行绘制,结果如下。
13. 雷达图 雷达图,可以可视化多个定量变量的一个或多个系列的值。
import matplotlib.pyplot as plt
import pandas as pd
from math import pi
df = pd.DataFrame({
'group' : ['A' , 'B' , 'C' , 'D' ],
'var1' : [38 , 1.5 , 30 , 4 ],
'var2' : [29 , 10 , 9 , 34 ],
'var3' : [8 , 39 , 23 , 24 ],
'var4' : [7 , 31 , 33 , 14 ],
'var5' : [28 , 15 , 32 , 14 ]
})
categories = list (df)[1 :]
N = len (categories)
angles = [n / float (N) * 2 * pi for n in range (N)]
angles += angles[:1 ]
ax = plt.subplot(111 , polar=True )
ax.set_theta_offset(pi / 2 )
ax.set_theta_direction(-1 )
plt.xticks(angles[:-1 ], categories)
ax.set_rlabel_position(0 )
plt.yticks([10 , 20 , 30 ], ["10" , "20" , "30" ], color="grey" , size=7 )
plt.ylim(0 , 40 )
values = df.loc[0 ].drop('group' ).values.flatten().tolist()
values += values[:1 ]
ax.plot(angles, values, linewidth=1 , linestyle='solid' , label="group A" )
ax.fill(angles, values, 'b' , alpha=0.1 )
values = df.loc[1 ].drop('group' ).values.flatten().tolist()
values += values[:1 ]
ax.plot(angles, values, linewidth=1 , linestyle='solid' , label="group B" )
ax.fill(angles, values, 'r' , alpha=0.1 )
plt.legend(loc='upper right' , bbox_to_anchor=(0.1 , 0.1 ))
plt.show()
14. 词云图 单词通常是单个的,每个单词的重要性以字体大小或颜色表示。
from wordcloud import WordCloud
import matplotlib.pyplot as plt
text=("Python Python Python Matplotlib Chart Wordcloud Boxplot" )
wordcloud = WordCloud(width=480 , height=480 , margin=0 ).generate(text)
plt.imshow(wordcloud, interpolation='bilinear' )
plt.axis("off" )
plt.margins(x=0 , y=0 )
plt.show()
15. 平行座标图 一个平行座标图,能够比较不同系列相同属性的数值情况。
import seaborn as sns
import matplotlib.pyplot as plt
from pandas.plotting import parallel_coordinates
data = sns.load_dataset('iris' , data_home='seaborn-data' , cache=True )
parallel_coordinates(data, 'species' , colormap=plt.get_cmap("Set2" ))
plt.show()
使用 Pandas 的 parallel_coordinates() 进行绘制,结果如下。
16. 棒棒糖图 棒棒糖图其实就是柱状图的变形,显示一个线段和一个圆。
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
df = pd.DataFrame({'group' : list (map (chr , range (65 , 85 ))), 'values' : np.random.uniform(size=20 ) })
ordered_df = df.sort_values(by='values' )
my_range = range (1 , len (df.index)+1 )
plt.stem(ordered_df['values' ])
plt.xticks(my_range, ordered_df['group' ])
plt.show()
使用 Matplotlib 的 stem() 进行绘制,结果如下。
17. 径向柱图 径向柱图同样也是条形图的变形,但是使用极坐标而不是直角坐标系。
绘制起来有点麻烦,而且比柱状图准确度低,但更引人注目。
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
df = pd.DataFrame(
{
'Name' : ['item ' + str (i) for i in list (range (1 , 51 )) ],
'Value' : np.random.randint(low=10 , high=100 , size=50 )
})
df = df.sort_values(by=['Value' ])
plt.figure(figsize=(20 , 10 ))
ax = plt.subplot(111 , polar=True )
plt.axis('off' )
upperLimit = 100
lowerLimit = 30
labelPadding = 4
max_val = df['Value' ].max ()
slope = (max_val - lowerLimit) / max_val
heights = slope * df.Value + lowerLimit
width = 2 *np.pi / len (df.index)
indexes = list (range (1 , len (df.index)+1 ))
angles = [element * width for element in indexes]
bars = ax.bar(
x=angles,
height=heights,
width=width,
bottom=lowerLimit,
linewidth=2 ,
edgecolor="white" ,
color="#61a4b2" ,
)
for bar, angle, height, label in zip (bars,angles, heights, df["Name" ]):
rotation = np.rad2deg(angle)
alignment = ""
if angle >= np.pi/2 and angle < 3 *np.pi/2 :
alignment = "right"
rotation = rotation + 180
else :
alignment = "left"
ax.text(
x=angle,
y=lowerLimit + bar.get_height() + labelPadding,
s=label,
ha=alignment,
va='center' ,
rotation=rotation,
rotation_mode="anchor" )
plt.show()
18. 矩形树图 矩形树图是一种常见的表达『层级数据』『树状数据』的可视化形式。
它主要用面积的方式,便于突出展现出『树』的各层级中重要的节点。
import matplotlib.pyplot as plt
import squarify
import pandas as pd
df = pd.DataFrame({'nb_people' : [8 , 3 , 4 , 2 ], 'group' : ["group A" , "group B" , "group C" , "group D" ]})
squarify.plot(sizes=df['nb_people' ], label=df['group' ], alpha=.8 )
plt.axis('off' )
plt.show()
19. 维恩图 import matplotlib.pyplot as plt
from matplotlib_venn import venn2
venn2(subsets=(10 , 5 , 2 ), set_labels=('Group A' , 'Group B' ))
plt.show()
使用 matplotlib_venn 库进行绘制,结果如下。
20. 圆环图 import matplotlib.pyplot as plt
size_of_groups = [12 , 11 , 3 , 30 ]
plt.pie(size_of_groups)
my_circle = plt.Circle((0 , 0 ), 0.7 , color='white' )
p = plt.gcf()
p.gca().add_artist(my_circle)
plt.show()
21. 饼图 将圆划分成一个个扇形区域,每个区域代表在整体中所占的比例。
import matplotlib.pyplot as plt
size_of_groups = [12 , 11 , 3 , 30 ]
plt.pie(size_of_groups)
plt.show()
22. 树图 树图主要用来可视化树形数据结构,是一种特殊的层次类型,具有唯一的根节点,左子树,和右子树。
import pandas as pd
from matplotlib import pyplot as plt
from scipy.cluster.hierarchy import dendrogram, linkage
df = pd.read_csv('mtcars.csv' )
df = df.set_index('model' )
Z = linkage(df, 'ward' )
dendrogram(Z, leaf_rotation=90 , leaf_font_size=8 , labels=df.index)
plt.show()
23. 气泡图 import circlify
import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=(14 , 14 ))
ax.set_title('Repartition of the world population' )
ax.axis('off' )
data = [{'id' : 'World' , 'datum' : 6964195249 , 'children' : [
{'id' : "North America" , 'datum' : 450448697 ,
'children' : [
{'id' : "United States" , 'datum' : 308865000 },
{'id' : "Mexico" , 'datum' : 107550697 },
{'id' : "Canada" , 'datum' : 34033000 }
]},
{'id' : "South America" , 'datum' : 278095425 ,
'children' : [
{'id' : "Brazil" , 'datum' : 192612000 },
{'id' : "Colombia" , 'datum' : 45349000 },
{'id' : "Argentina" , 'datum' : 40134425 }
]},
{'id' : "Europe" , 'datum' : 209246682 ,
'children' : [
{'id' : "Germany" , 'datum' : 81757600 },
{'id' : "France" , 'datum' : 65447374 },
{'id' : "United Kingdom" , 'datum' : 62041708 }
]},
{'id' : "Africa" , 'datum' : 311929000 ,
'children' : [
{'id' : "Nigeria" , 'datum' : 154729000 },
{'id' : "Ethiopia" , 'datum' : 79221000 },
{'id' : "Egypt" , 'datum' : 77977000 }
]},
{'id' : "Asia" , 'datum' : 2745929500 ,
'children' : [
{'id' : "China" , 'datum' : 1336335000 },
{'id' : "India" , 'datum' : 1178225000 },
{'id' : "Indonesia" , 'datum' : 231369500 }
]}
]}]
circles = circlify.circlify(
data,
show_enclosure=False ,
target_enclosure=circlify.Circle(x=0 , y=0 , r=1 )
)
lim = max (
max (
abs (circle.x) + circle.r,
abs (circle.y) + circle.r,
)
for circle in circles
)
plt.xlim(-lim, lim)
plt.ylim(-lim, lim)
for circle in circles:
if circle.level != 2 :
continue
x, y, r = circle
ax.add_patch(plt.Circle((x, y), r, alpha=0.5 , linewidth=2 , color="lightblue" ))
for circle in circles:
if circle.level != 3 :
continue
x, y, r = circle
label = circle.ex["id" ]
ax.add_patch(plt.Circle((x, y), r, alpha=0.5 , linewidth=2 , color="#69b3a2" ))
plt.annotate(label, (x, y), ha='center' , color="white" )
for circle in circles:
if circle.level != 2 :
continue
x, y, r = circle
label = circle.ex["id" ]
plt.annotate(label, (x, y), va='center' , ha='center' , bbox=dict (facecolor='white' , edgecolor='black' , boxstyle='round' , pad=.5 ))
plt.show()
24. 折线图 将各个数据点标志连接起来的图表,用于展现数据的变化趋势。
import matplotlib.pyplot as plt
import numpy as np
values = np.cumsum(np.random.randn(1000 , 1 ))
plt.plot(values)
plt.show()
25. 面积图 面积图和折线图非常相似,区别在于和 x 坐标轴间是否被颜色填充。
import matplotlib.pyplot as plt
x = range (1 , 6 )
y = [1 , 4 , 6 , 8 , 4 ]
plt.fill_between(x, y)
plt.show()
使用 Matplotlib 的 fill_between() 进行绘制,结果如下。
26. 堆叠面积图 每个显示在彼此的顶部,易于读取总数,但较难准确读取每个的值。
import matplotlib.pyplot as plt
x = range (1 , 6 )
y1 = [1 , 4 , 6 , 8 , 9 ]
y2 = [2 , 2 , 7 , 10 , 12 ]
y3 = [2 , 8 , 5 , 10 , 6 ]
plt.stackplot(x, y1, y2, y3, labels=['A' , 'B' , 'C' ])
plt.legend(loc='upper left' )
plt.show()
使用 Matplotlib 的 stackplot() 进行绘制,结果如下。
27. 河流图 河流图是一种特殊的流图,它主要用来表示事件或主题等在一段时间内的变化。
围绕着中心轴显示,且边缘是圆形的,从而形成流动的形状。
import matplotlib.pyplot as plt
import numpy as np
from scipy import stats
x = np.arange(1990 , 2020 )
y = [np.random.randint(0 , 5 , size=30 ) for _ in range (5 )]
def gaussian_smooth (x, y, grid, sd ):
"""平滑曲线"""
weights = np.transpose([stats.norm.pdf(grid, m, sd) for m in x])
weights = weights / weights.sum (0 )
return (weights * y).sum (1 )
COLORS = ["#D0D1E6" , "#A6BDDB" , "#74A9CF" , "#2B8CBE" , "#045A8D" ]
fig, ax = plt.subplots(figsize=(10 , 7 ))
grid = np.linspace(1985 , 2025 , num=500 )
y_smoothed = [gaussian_smooth(x, y_, grid, 1 ) for y_ in y]
ax.stackplot(grid, y_smoothed, colors=COLORS, baseline="sym" )
plt.show()
先使用 Matplotlib 绘制堆积图,设置 stackplot() 的 baseline 参数,可将数据围绕 x 轴展示。
再通过 scipy.interpolate 平滑曲线,最终结果如下。
28. 时间序列图 import numpy as np
import seaborn as sns
import pandas as pd
import matplotlib.pyplot as plt
my_count = ["France" , "Australia" , "Japan" , "USA" , "Germany" , "Congo" , "China" , "England" , "Spain" , "Greece" , "Marocco" ,
"South Africa" , "Indonesia" , "Peru" , "Chili" , "Brazil" ]
df = pd.DataFrame({
"country" : np.repeat(my_count, 10 ),
"years" : list (range (2000 , 2010 )) * 16 ,
"value" : np.random.rand(160 )
})
g = sns.FacetGrid(df, col='country' , hue='country' , col_wrap=4 , )
g = g.map (plt.plot, 'years' , 'value' )
g = g.map (plt.fill_between, 'years' , 'value' , alpha=0.2 ).set_titles("{col_name} country" )
g = g.set_titles("{col_name}" )
plt.subplots_adjust(top=0.92 )
g = g.fig.suptitle('Evolution of the value of stuff in 16 countries' )
plt.show()
下面以一个时间序列面积图为例,显示多组数据,结果如下。
29. 地图 import pandas as pd
import folium
m = folium.Map(location=[20 , 0 ], tiles="OpenStreetMap" , zoom_start=2 )
data = pd.DataFrame({
'lon' : [-58 , 2 , 145 , 30.32 , -4.03 , -73.57 , 36.82 , -38.5 ],
'lat' : [-34 , 49 , -38 , 59.93 , 5.33 , 45.52 , -1.29 , -12.97 ],
'name' : ['Buenos Aires' , 'Paris' , 'melbourne' , 'St Petersbourg' , 'Abidjan' , 'Montreal' , 'Nairobi' , 'Salvador' ],
'value' : [10 , 12 , 40 , 70 , 23 , 43 , 100 , 43 ]
}, dtype=str )
for i in range (0 ,len (data)):
folium.Marker(
location=[data.iloc[i]['lat' ], data.iloc[i]['lon' ]],
popup=data.iloc[i]['name' ],
).add_to(m)
m.save('map.html' )
使用 Folium 绘制谷歌地图风格的地图,结果如下。
30. 等值域地图 import pandas as pd
import folium
m = folium.Map(location=[40 , -95 ], zoom_start=4 )
state_geo = f"us-states.json"
state_unemployment = f"US_Unemployment_Oct2012.csv"
state_data = pd.read_csv(state_unemployment)
folium.Choropleth(
geo_data=state_geo,
name="choropleth" ,
data=state_data,
columns=["State" , "Unemployment" ],
key_on="feature.id" ,
fill_color="YlGn" ,
fill_opacity=0.7 ,
line_opacity=.1 ,
legend_name="Unemployment Rate (%)" ,
).add_to(m)
folium.LayerControl().add_to(m)
m.save('choropleth-map.html' )
使用 Folium 的 choropleth() 进行绘制,结果如下。
31. 网格地图 import pandas as pd
import geopandas as gpd
import matplotlib.pyplot as plt
file = "us_states_hexgrid.geojson.json"
geoData = gpd.read_file(file)
geoData['centroid' ] = geoData['geometry' ].apply(lambda x: x.centroid)
mariageData = pd.read_csv("State_mariage_rate.csv" )
geoData['state' ] = geoData['google_name' ].str .replace(' (United States)' ,'' )
geoData = geoData.set_index('state' ).join(mariageData.set_index('state' ))
fig, ax = plt.subplots(1 , figsize=(6 , 4 ))
geoData.plot(
ax=ax,
column="y_2015" ,
cmap="BuPu" ,
norm=plt.Normalize(vmin=2 , vmax=13 ),
edgecolor='black' ,
linewidth=.5
);
ax.axis('off' )
ax.annotate('Mariage rate in the US' , xy=(10 , 340 ), xycoords='axes pixels' , horizontalalignment='left' , verticalalignment='top' , fontsize=14 , color='black' )
ax.annotate('Yes, people love to get married in Vegas' , xy=(10 , 320 ), xycoords='axes pixels' , horizontalalignment='left' , verticalalignment='top' , fontsize=11 , color='#808080' )
for idx, row in geoData.iterrows():
ax.annotate(
s=row['iso3166_2' ],
xy=row['centroid' ].coords[0 ],
horizontalalignment='center' ,
va='center' ,
color="white"
)
sm = plt.cm.ScalarMappable(cmap='BuPu' , norm=plt.Normalize(vmin=2 , vmax=13 ))
fig.colorbar(sm, orientation="horizontal" , aspect=50 , fraction=0.005 , pad=0 );
plt.show()
使用 geopandas 和 matplotlib 进行绘制,结果如下。
32. 变形地图
33. 连接映射地图 from mpl_toolkits.basemap import Basemap
import matplotlib.pyplot as plt
import pandas as pd
cities = {
'city' : ["Paris" , "Melbourne" , "Saint.Petersburg" , "Abidjan" , "Montreal" , "Nairobi" , "Salvador" ],
'lon' : [2 , 145 , 30.32 , -4.03 , -73.57 , 36.82 , -38.5 ],
'lat' : [49 , -38 , 59.93 , 5.33 , 45.52 , -1.29 , -12.97 ]
}
df = pd.DataFrame(cities, columns=['city' , 'lon' , 'lat' ])
m = Basemap(llcrnrlon=-179 , llcrnrlat=-60 , urcrnrlon=179 , urcrnrlat=70 , projection='merc' )
m.drawmapboundary(fill_color='white' , linewidth=0 )
m.fillcontinents(color='#f2f2f2' , alpha=0.7 )
m.drawcoastlines(linewidth=0.1 , color="white" )
for startIndex, startRow in df.iterrows():
for endIndex in range (startIndex, len (df.index)):
endRow = df.iloc[endIndex]
m.drawgreatcircle(startRow.lon, startRow.lat, endRow.lon, endRow.lat, linewidth=1 , color='#69b3a2' );
for i, row in df.iterrows():
plt.annotate(row.city, xy=m(row.lon + 3 , row.lat), verticalalignment='center' )
plt.show()
34. 气泡地图 气泡地图,使用不同尺寸的圆来表示该地理坐标的数值。
import folium
import pandas as pd
m = folium.Map(location=[20 ,0 ], tiles="OpenStreetMap" , zoom_start=2 )
data = pd.DataFrame({
'lon' : [-58 , 2 , 145 , 30.32 , -4.03 , -73.57 , 36.82 , -38.5 ],
'lat' : [-34 , 49 , -38 , 59.93 , 5.33 , 45.52 , -1.29 , -12.97 ],
'name' : ['Buenos Aires' , 'Paris' , 'melbourne' , 'St Petersbourg' , 'Abidjan' , 'Montreal' , 'Nairobi' , 'Salvador' ],
'value' : [10 , 12 , 40 , 70 , 23 , 43 , 100 , 43 ]
}, dtype=str )
for i in range (0 , len (data)):
folium.Circle(
location=[data.iloc[i]['lat' ], data.iloc[i]['lon' ]],
popup=data.iloc[i]['name' ],
radius=float (data.iloc[i]['value' ])*20000 ,
color='crimson' ,
fill=True ,
fill_color='crimson'
).add_to(m)
m.save('bubble-map.html' )
使用 Folium 的 Circle() 进行绘制,结果如下。
35. 和弦图 每个实体 (节点) 有圆形布局外部的一个片段表示。
然后在每个实体之间绘制弧线,弧线的大小与流的关系成正比。
from chord import Chord
matrix = [
[0 , 5 , 6 , 4 , 7 , 4 ],
[5 , 0 , 5 , 4 , 6 , 5 ],
[6 , 5 , 0 , 4 , 5 , 5 ],
[4 , 4 , 4 , 0 , 5 , 5 ],
[7 , 6 , 5 , 5 , 0 , 4 ],
[4 , 5 , 5 , 5 , 4 , 0 ],
]
names = ["Action" , "Adventure" , "Comedy" , "Drama" , "Fantasy" , "Thriller" ]
Chord(matrix, names).to_html("chord-diagram.html" )
36. 网状图 import pandas as pd
import numpy as np
import networkx as nx
import matplotlib.pyplot as plt
ind1 = [5 , 10 , 3 , 4 , 8 , 10 , 12 , 1 , 9 , 4 ]
ind5 = [1 , 1 , 13 , 4 , 18 , 5 , 2 , 11 , 3 , 8 ]
df = pd.DataFrame(
{'A' : ind1, 'B' : ind1 + np.random.randint(10 , size=(10 )), 'C' : ind1 + np.random.randint(10 , size=(10 )),
'D' : ind1 + np.random.randint(5 , size=(10 )), 'E' : ind1 + np.random.randint(5 , size=(10 )), 'F' : ind5,
'G' : ind5 + np.random.randint(5 , size=(10 )), 'H' : ind5 + np.random.randint(5 , size=(10 )),
'I' : ind5 + np.random.randint(5 , size=(10 )), 'J' : ind5 + np.random.randint(5 , size=(10 ))})
corr = df.corr()
links = corr.stack().reset_index()
links.columns = ['var1' , 'var2' , 'value' ]
links_filtered = links.loc[(links['value' ] > 0.8 ) & (links['var1' ] != links['var2' ])]
G = nx.from_pandas_edgelist(links_filtered, 'var1' , 'var2' )
nx.draw(G, with_labels=True , node_color='orange' , node_size=400 , edge_color='black' , linewidths=1 , font_size=15 )
plt.show()
37. 桑基图 它主要用来表示原材料、能量等如何从初始形式经过中间过程的加工、转化到达最终形式。
Plotly 可能是创建桑基图的最佳工具,通过 Sankey() 在几行代码中获得一个图表。
import plotly.graph_objects as go
import json
with open ('sankey_energy.json' ) as f:
data = json.load(f)
opacity = 0.4
data['data' ][0 ]['node' ]['color' ] = ['rgba(255,0,255, 0.8)' if color == "magenta" else color for color in data['data' ][0 ]['node' ]['color' ]]
data['data' ][0 ]['link' ]['color' ] = [data['data' ][0 ]['node' ]['color' ][src].replace("0.8" , str (opacity)) for src in data['data' ][0 ]['link' ]['source' ]]
fig = go.Figure(data=[go.Sankey(
valueformat=".0f" ,
valuesuffix="TWh" ,
node=dict (
pad=15 ,
thickness=15 ,
line=dict (color = "black" , width = 0.5 ),
label=data['data' ][0 ]['node' ]['label' ],
color=data['data' ][0 ]['node' ]['color' ]
),
link=dict (
source=data['data' ][0 ]['link' ]['source' ],
target=data['data' ][0 ]['link' ]['target' ],
value=data['data' ][0 ]['link' ]['value' ],
label=data['data' ][0 ]['link' ]['label' ],
color=data['data' ][0 ]['link' ]['color' ]
))])
fig.update_layout(title_text="Energy forecast for 2050\nSource: Department of Energy & Climate Change, Tom Counsell via Mike Bostock" ,
font_size=10 )
fig.write_html("sankey-diagram.html" )
38. 弧线图 在弧线图中,节点沿单个轴显示,节点间通过圆弧线进行连接。
目前还不知道如何通过 Python 来构建弧线图,不过可以使用 R 或者 D3.js。
39. 环形布局关系图 可视化目标之间的关系,可以减少复杂网络下观察混乱。
和弧线图一样,也只能通 R 或者 D3.js 绘制。
40. 动态图表 import imageio
import pandas as pd
import matplotlib.pyplot as plt
data = pd.read_csv('gapminderData.csv' )
data['continent' ] = pd.Categorical(data['continent' ])
dpi = 96
filenames = []
for i in data.year.unique():
plt.ioff()
fig = plt.figure(figsize=(680 / dpi, 480 / dpi), dpi=dpi)
subsetData = data[data.year == i]
plt.scatter(
x=subsetData['lifeExp' ],
y=subsetData['gdpPercap' ],
s=subsetData['pop' ] / 200000 ,
c=subsetData['continent' ].cat.codes,
cmap="Accent" , alpha=0.6 , edgecolors="white" , linewidth=2 )
plt.yscale('log' )
plt.xlabel("Life Expectancy" )
plt.ylabel("GDP per Capita" )
plt.title("Year: " + str (i))
plt.ylim(0 , 100000 )
plt.xlim(30 , 90 )
filename = './images/' + str (i) + '.png'
filenames.append(filename)
plt.savefig(fname=filename, dpi=96 )
plt.gca()
plt.close(fig)
with imageio.get_writer('result.gif' , mode='I' , fps=5 ) as writer:
for filename in filenames:
image = imageio.imread(filename)
writer.append_data(image)
先用 matplotlib 绘制图表图片,再通过 imageio 生成 GIF,结果如下。
相关免费在线工具 加密/解密文本 使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
RSA密钥对生成器 生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online
Mermaid 预览与可视化编辑 基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online
随机西班牙地址生成器 随机生成西班牙地址(支持马德里、加泰罗尼亚、安达卢西亚、瓦伦西亚筛选),支持数量快捷选择、显示全部与下载。 在线工具,随机西班牙地址生成器在线工具,online
Gemini 图片去水印 基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online
curl 转代码 解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online