Matplotlib散点图:自定义标记和大小的完整指南
参考:matplotlib scatter marker size
Matplotlib是Python中最流行的数据可视化库之一,它提供了强大而灵活的工具来创建各种类型的图表。在数据分析和科学研究中,散点图是一种常用的可视化方法,用于展示两个变量之间的关系。Matplotlib的scatter函数允许用户创建散点图,并通过调整标记(marker)的类型和大小来增强图表的表现力和信息量。本文将深入探讨如何使用Matplotlib创建散点图,并重点介绍如何自定义标记的样式和大小。
1. Matplotlib散点图基础
在开始深入探讨标记和大小的自定义之前,让我们先了解一下如何使用Matplotlib创建基本的散点图。
import matplotlib.pyplot as plt
import numpy as np
# 生成示例数据
x = np.linspace(0, 10, 50)
y = np.sin(x)
# 创建散点图
plt.figure(figsize=(10, 6))
plt.scatter(x, y)
plt.title('Basic Scatter Plot - how2matplotlib.com')
plt.xlabel('X-axis')
plt.ylabel('Y-axis')
plt.show()
Output:
在这个基本示例中,我们使用plt.scatter()
函数创建了一个简单的散点图。x
和y
是包含数据点坐标的NumPy数组。plt.figure()
用于设置图表的大小,plt.title()
、plt.xlabel()
和plt.ylabel()
分别用于设置图表标题和轴标签。
2. 自定义标记类型
Matplotlib提供了多种标记类型,可以通过marker
参数来指定。以下是一些常用的标记类型:
- ‘o’: 圆形
- ‘s’: 正方形
- ‘^’: 上三角形
- ‘v’: 下三角形
- ‘*’: 星形
- ‘+’: 加号
- ‘x’: 叉号
让我们看一个使用不同标记类型的示例:
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, 10, 10)
y1 = np.sin(x)
y2 = np.cos(x)
plt.figure(figsize=(12, 6))
plt.scatter(x, y1, marker='o', label='Sin - how2matplotlib.com')
plt.scatter(x, y2, marker='^', label='Cos - how2matplotlib.com')
plt.legend()
plt.title('Scatter Plot with Different Markers - how2matplotlib.com')
plt.xlabel('X-axis')
plt.ylabel('Y-axis')
plt.show()
Output:
在这个示例中,我们创建了两个散点序列,一个使用圆形标记(’o’)表示正弦函数,另一个使用上三角形标记(’^’)表示余弦函数。通过使用不同的标记,我们可以轻松区分两组数据。
3. 调整标记大小
标记的大小可以通过s
参数来控制。这个参数可以是一个单一的数值,用于所有点,也可以是一个数组,为每个点指定不同的大小。
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, 10, 20)
y = np.sin(x)
sizes = np.linspace(20, 200, 20)
plt.figure(figsize=(12, 6))
plt.scatter(x, y, s=sizes)
plt.title('Scatter Plot with Varying Marker Sizes - how2matplotlib.com')
plt.xlabel('X-axis')
plt.ylabel('Y-axis')
plt.show()
Output:
在这个例子中,我们使用sizes
数组来指定每个点的大小。点的大小从20到200线性增加,创造出一种视觉上的深度效果。
4. 使用颜色映射
结合标记大小和颜色映射,我们可以在散点图中表示更多维度的信息:
import matplotlib.pyplot as plt
import numpy as np
x = np.random.rand(50)
y = np.random.rand(50)
colors = np.random.rand(50)
sizes = 1000 * np.random.rand(50)
plt.figure(figsize=(12, 8))
plt.scatter(x, y, c=colors, s=sizes, alpha=0.5, cmap='viridis')
plt.colorbar(label='Color Value - how2matplotlib.com')
plt.title('Scatter Plot with Color Map and Varying Sizes - how2matplotlib.com')
plt.xlabel('X-axis')
plt.ylabel('Y-axis')
plt.show()
Output:
这个示例展示了如何使用颜色映射和不同大小的标记来表示四个维度的数据。c
参数用于指定颜色值,cmap
参数选择颜色映射方案,alpha
参数控制透明度。
5. 自定义标记样式
除了使用预定义的标记,Matplotlib还允许我们创建自定义标记:
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, 10, 10)
y = np.sin(x)
plt.figure(figsize=(12, 6))
plt.scatter(x, y, marker='\heartsuit', s=500, color='red')
plt.title('Scatter Plot with Custom Heart Marker - how2matplotlib.com')
plt.xlabel('X-axis')
plt.ylabel('Y-axis')
plt.show()
Output:
在这个例子中,我们使用了一个心形符号作为自定义标记。通过将Unicode字符包裹在’$’符号中,我们可以将任何支持的符号或文本用作标记。
6. 使用标记大小表示数据
标记大小不仅可以用于美化图表,还可以用来表示数据的另一个维度:
import matplotlib.pyplot as plt
import numpy as np
x = np.random.rand(50)
y = np.random.rand(50)
population = np.random.randint(100, 1000, 50)
plt.figure(figsize=(12, 8))
plt.scatter(x, y, s=population, alpha=0.5)
plt.title('City Population Representation - how2matplotlib.com')
plt.xlabel('Longitude')
plt.ylabel('Latitude')
plt.show()
Output:
在这个示例中,我们模拟了一个表示城市位置和人口的散点图。每个点的位置由x和y坐标确定,而点的大小则代表城市的人口。
7. 组合多个散点图
有时我们需要在同一个图表中比较多组数据:
import matplotlib.pyplot as plt
import numpy as np
np.random.seed(0)
x1 = np.random.rand(50)
y1 = np.random.rand(50)
x2 = np.random.rand(50) + 0.5
y2 = np.random.rand(50) + 0.5
plt.figure(figsize=(12, 8))
plt.scatter(x1, y1, s=100, c='blue', alpha=0.5, label='Group A - how2matplotlib.com')
plt.scatter(x2, y2, s=200, c='red', alpha=0.5, label='Group B - how2matplotlib.com')
plt.legend()
plt.title('Comparison of Two Groups - how2matplotlib.com')
plt.xlabel('X-axis')
plt.ylabel('Y-axis')
plt.show()
Output:
这个例子展示了如何在同一个图表中绘制两组散点数据,使用不同的颜色和大小来区分它们。
8. 使用标记大小表示误差
在科学数据可视化中,我们经常需要表示数据点的不确定性或误差范围:
import matplotlib.pyplot as plt
import numpy as np
x = np.linspace(0, 10, 20)
y = np.sin(x)
error = np.random.rand(20) * 0.1
plt.figure(figsize=(12, 8))
plt.scatter(x, y, s=error*1000, alpha=0.5)
plt.errorbar(x, y, yerr=error, fmt='none', ecolor='red', capsize=5)
plt.title('Scatter Plot with Error Representation - how2matplotlib.com')
plt.xlabel('X-axis')
plt.ylabel('Y-axis')
plt.show()
Output:
在这个示例中,我们使用标记大小来表示每个数据点的误差大小,同时使用误差条来显示具体的误差范围。
9. 3D散点图
Matplotlib还支持创建3D散点图,这在某些科学可视化场景中非常有用:
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
fig = plt.figure(figsize=(12, 8))
ax = fig.add_subplot(111, projection='3d')
n = 100
x = np.random.rand(n)
y = np.random.rand(n)
z = np.random.rand(n)
colors = np.random.rand(n)
sizes = 1000 * np.random.rand(n)
scatter = ax.scatter(x, y, z, c=colors, s=sizes, alpha=0.6, cmap='viridis')
ax.set_xlabel('X-axis')
ax.set_ylabel('Y-axis')
ax.set_zlabel('Z-axis')
plt.colorbar(scatter, label='Color Value - how2matplotlib.com')
plt.title('3D Scatter Plot - how2matplotlib.com')
plt.show()
Output:
这个3D散点图示例展示了如何在三维空间中表示数据点,并使用颜色和大小来表示额外的数据维度。
10. 使用标记大小表示时间序列
标记大小还可以用来表示时间序列数据中的时间流逝:
import matplotlib.pyplot as plt
import numpy as np
np.random.seed(0)
days = np.arange(30)
temperature = 20 + np.random.randn(30) * 5
sizes = np.linspace(20, 200, 30)
plt.figure(figsize=(12, 6))
scatter = plt.scatter(days, temperature, s=sizes, c=days, cmap='viridis')
plt.colorbar(scatter, label='Day - how2matplotlib.com')
plt.title('Temperature Variation over a Month - how2matplotlib.com')
plt.xlabel('Day')
plt.ylabel('Temperature (°C)')
plt.show()
Output:
在这个例子中,我们使用点的大小来表示时间的推移,颜色则用来强化这一效果。这种可视化方法可以有效地展示温度随时间的变化趋势。
11. 使用不同形状的标记
有时,使用不同形状的标记可以更好地区分不同类别的数据:
import matplotlib.pyplot as plt
import numpy as np
np.random.seed(0)
x = np.random.rand(3, 20)
y = np.random.rand(3, 20)
markers = ['o', 's', '^']
colors = ['red', 'green', 'blue']
labels = ['Category A', 'Category B', 'Category C']
plt.figure(figsize=(12, 8))
for i in range(3):
plt.scatter(x[i], y[i], marker=markers[i], c=colors[i], s=100, alpha=0.7, label=f'{labels[i]} - how2matplotlib.com')
plt.legend()
plt.title('Scatter Plot with Different Marker Shapes - how2matplotlib.com')
plt.xlabel('X-axis')
plt.ylabel('Y-axis')
plt.show()
Output:
这个示例展示了如何使用不同的标记形状来区分三个不同的数据类别,同时使用不同的颜色来进一步增强可读性。
12. 使用标记大小表示分类数据
标记大小不仅可以用于连续数据,还可以用于表示分类数据:
import matplotlib.pyplot as plt
import numpy as np
np.random.seed(0)
x = np.random.rand(100)
y = np.random.rand(100)
categories = np.random.choice(['A', 'B', 'C'], 100)
sizes = {'A': 50, 'B': 100, 'C': 200}
plt.figure(figsize=(12, 8))
for category in ['A', 'B', 'C']:
mask = categories == category
plt.scatter(x[mask], y[mask], s=sizes[category], alpha=0.6, label=f'Category {category} - how2matplotlib.com')
plt.legend()
plt.title('Scatter Plot with Categorical Marker Sizes - how2matplotlib.com')
plt.xlabel('X-axis')
plt.ylabel('Y-axis')
plt.show()
Output:
在这个例子中,我们使用不同的标记大小来表示不同的类别,这种方法在可视化分类数据时特别有用。
13. 结合箱线图和散点图
有时,将散点图与其他类型的图表结合可以提供更全面的数据视图:
import matplotlib.pyplot as plt
import numpy as np
np.random.seed(0)
data = [np.random.normal(0, std, 100) for std in range(1, 4)]
fig, (ax1, ax2) = plt.subplots(ncols=2, figsize=(16, 6), sharex=True, sharey=True)
# 箱线图
ax1.boxplot(data)
ax1.set_xticklabels(['Group 1', 'Group 2', 'Group 3'])
ax1.set_title('Box Plot - how2matplotlib.com')
# 散点图
for i, d in enumerate(data):
y = d
x = np.random.normal(i+1, 0.04, len(y))
ax2.scatter(x, y, alpha=0.4)
ax2.set_xlim(0.5, 3.5)
ax2.set_xticklabels(['Group 1', 'Group 2', 'Group 3'])
ax2.set_title('Scatter Plot - how2matplotlib.com')
plt.tight_layout()
plt.show()
Output:
这个示例展示了如何将箱线图和散点图结合起来。左侧的箱线图显示了数据的整体分布,而右侧的散点图则展示了每个数据点的具体位置。这种组合可以同时提供数据的统计概览和详细分布。
14. 使用标记大小表示聚类结果
在机器学习和数据挖掘中,散点图常用于可视化聚类结果。我们可以使用标记大小来表示每个点所属簇的重要性或大小:
import matplotlib.pyplot as plt
import numpy as np
from sklearn.cluster import KMeans
np.random.seed(0)
X = np.random.randn(300, 2)
kmeans = KMeans(n_clusters=3)
kmeans.fit(X)
y_kmeans = kmeans.predict(X)
plt.figure(figsize=(12, 8))
scatter = plt.scatter(X[:, 0], X[:, 1], c=y_kmeans, s=(y_kmeans + 1) * 100,
cmap='viridis', alpha=0.7)
centers = kmeans.cluster_centers_
plt.scatter(centers[:, 0], centers[:, 1], c='red', s=300, alpha=0.5, marker='*')
plt.colorbar(scatter, label='Cluster - how2matplotlib.com')
plt.title('K-means Clustering Visualization - how2matplotlib.com')
plt.xlabel('Feature 1')
plt.ylabel('Feature 2')
plt.show()
Output:
在这个例子中,我们使用K-means算法对数据进行聚类,然后用散点图可视化结果。点的颜色表示所属的簇,而点的大小则与簇的编号相关。簇的中心用更大的星形标记表示。
15. 使用标记大小表示时间序列中的异常值
在时间序列分析中,我们经常需要突出显示异常值。标记大小可以很好地用于这个目的:
import matplotlib.pyplot as plt
import numpy as np
np.random.seed(0)
dates = pd.date_range(start='2023-01-01', periods=100)
values = np.cumsum(np.random.randn(100))
anomalies = np.random.choice(range(100), 5, replace=False)
values[anomalies] += np.random.randn(5) * 10
plt.figure(figsize=(14, 6))
plt.plot(dates, values, color='blue', alpha=0.7)
plt.scatter(dates, values, s=20, color='blue', alpha=0.7)
plt.scatter(dates[anomalies], values[anomalies], s=200, color='red', alpha=0.7)
plt.title('Time Series with Anomalies - how2matplotlib.com')
plt.xlabel('Date')
plt.ylabel('Value')
plt.xticks(rotation=45)
plt.tight_layout()
plt.show()
在这个示例中,我们创建了一个时间序列数据,并随机选择了一些点作为异常值。通过使用更大的红色标记来表示这些异常值,我们可以轻松地在图表中识别它们。
16. 使用标记大小表示地理数据
在地理数据可视化中,标记大小可以用来表示各个位置的某种属性,比如人口或经济指标:
import matplotlib.pyplot as plt
import numpy as np
np.random.seed(0)
latitudes = np.random.uniform(30, 50, 50)
longitudes = np.random.uniform(-120, -70, 50)
populations = np.random.randint(10000, 1000000, 50)
plt.figure(figsize=(12, 8))
scatter = plt.scatter(longitudes, latitudes, s=populations/5000,
c=populations, cmap='viridis', alpha=0.6)
plt.colorbar(scatter, label='Population - how2matplotlib.com')
plt.title('City Populations across North America - how2matplotlib.com')
plt.xlabel('Longitude')
plt.ylabel('Latitude')
plt.show()
Output:
这个例子模拟了北美洲的城市分布,使用标记大小和颜色来表示每个城市的人口。这种可视化方法可以快速展示人口分布的地理模式。
17. 使用标记大小表示网络图中的节点重要性
在网络分析中,散点图可以用来可视化网络结构,而标记大小则可以表示节点的重要性或连接度:
import matplotlib.pyplot as plt
import networkx as nx
import numpy as np
G = nx.random_geometric_graph(20, 0.3)
pos = nx.spring_layout(G)
degrees = dict(G.degree())
node_sizes = [v * 100 for v in degrees.values()]
plt.figure(figsize=(12, 8))
nx.draw_networkx_edges(G, pos, alpha=0.2)
nodes = nx.draw_networkx_nodes(G, pos, node_size=node_sizes,
node_color=list(degrees.values()),
cmap='viridis')
plt.colorbar(nodes, label='Node Degree - how2matplotlib.com')
plt.title('Network Graph with Node Sizes Representing Degree - how2matplotlib.com')
plt.axis('off')
plt.tight_layout()
plt.show()
Output:
在这个网络图示例中,我们使用节点的大小来表示其度(连接数),颜色也用来强化这一信息。这种可视化方法可以直观地展示网络中的重要节点。
18. 使用标记大小表示多维数据
当处理多维数据时,我们可以使用散点图的x和y坐标表示两个维度,然后用标记大小和颜色来表示额外的维度:
import matplotlib.pyplot as plt
import numpy as np
np.random.seed(0)
data = np.random.rand(100, 4) # 4维数据
plt.figure(figsize=(12, 8))
scatter = plt.scatter(data[:, 0], data[:, 1], s=data[:, 2]*500, c=data[:, 3],
cmap='viridis', alpha=0.6)
plt.colorbar(scatter, label='Dimension 4 - how2matplotlib.com')
plt.title('4-Dimensional Data Visualization - how2matplotlib.com')
plt.xlabel('Dimension 1')
plt.ylabel('Dimension 2')
plt.text(0.05, 0.95, 'Marker size represents Dimension 3',
transform=plt.gca().transAxes, verticalalignment='top')
plt.show()
Output:
这个例子展示了如何在一个二维平面上可视化四维数据。x和y坐标表示前两个维度,标记大小表示第三个维度,颜色表示第四个维度。
总结
通过本文的详细探讨,我们深入了解了如何使用Matplotlib创建散点图,并重点介绍了如何自定义标记的样式和大小。我们学习了如何:
- 创建基本的散点图
- 自定义标记类型
- 调整标记大小
- 使用颜色映射增加数据维度
- 创建自定义标记
- 使用标记大小表示数据
- 组合多个散点图
- 表示数据的误差或不确定性
- 创建3D散点图
- 使用标记大小表示时间序列数据
- 使用不同形状的标记区分类别
- 使用标记大小表示分类数据
- 结合箱线图和散点图
- 可视化聚类结果
- 突出显示时间序列中的异常值
- 可视化地理数据
- 表示网络图中节点的重要性
- 可视化多维数据
这些技巧和方法可以帮助数据科学家、研究人员和分析师更有效地探索和展示他们的数据。通过合理使用标记类型、大小、颜色和其他视觉元素,我们可以在一个简单的散点图中传达丰富的信息。
记住,好的数据可视化不仅仅是about美观,更重要的是要能够清晰、准确地传达数据中的关键信息。在创建散点图时,始终要考虑你的目标受众和你想要传达的主要信息。通过实践和不断尝试,你将能够掌握这些技巧,创建出既美观又富有洞察力的数据可视化作品。