Matplotlib散点图:如何创建包含正负轴的散点图
参考:How to create scatterplot with both negative and positive axes
Matplotlib是Python中最流行的数据可视化库之一,它提供了强大而灵活的工具来创建各种类型的图表,包括散点图。在本文中,我们将深入探讨如何使用Matplotlib创建包含正负轴的散点图,这种图表在展示跨越原点的数据分布时特别有用。
1. 散点图基础
散点图是一种用于显示两个变量之间关系的图表类型。每个点代表一个观察值,其x坐标和y坐标分别对应两个变量的值。散点图可以帮助我们识别变量之间的相关性、聚类模式或异常值。
让我们从一个简单的散点图开始:
import matplotlib.pyplot as plt
import numpy as np
# 生成示例数据
x = np.random.randn(100)
y = np.random.randn(100)
# 创建散点图
plt.figure(figsize=(8, 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坐标作为输入。
2. 创建包含正负轴的散点图
要创建包含正负轴的散点图,我们需要确保数据点分布在坐标系的四个象限中。这通常涉及到使用跨越零点的数据。以下是一个示例:
import matplotlib.pyplot as plt
import numpy as np
# 生成跨越零点的数据
x = np.random.uniform(-5, 5, 100)
y = np.random.uniform(-5, 5, 100)
# 创建散点图
plt.figure(figsize=(8, 8))
plt.scatter(x, y)
plt.axhline(y=0, color='k', linestyle='--')
plt.axvline(x=0, color='k', linestyle='--')
plt.title('Scatter Plot with Positive and Negative Axes - how2matplotlib.com')
plt.xlabel('X-axis')
plt.ylabel('Y-axis')
plt.grid(True)
plt.show()
Output:
在这个例子中,我们使用np.random.uniform()
生成了在-5到5之间均匀分布的数据点。plt.axhline()
和plt.axvline()
函数用于绘制穿过原点的水平和垂直线,以清晰地显示坐标轴。
3. 自定义散点图外观
Matplotlib提供了多种方法来自定义散点图的外观,使其更具吸引力和信息量。以下是一些常用的自定义选项:
3.1 调整点的大小和颜色
import matplotlib.pyplot as plt
import numpy as np
x = np.random.uniform(-5, 5, 100)
y = np.random.uniform(-5, 5, 100)
colors = np.random.rand(100)
sizes = np.random.randint(20, 200, 100)
plt.figure(figsize=(10, 8))
plt.scatter(x, y, c=colors, s=sizes, alpha=0.6, cmap='viridis')
plt.colorbar(label='Color Scale')
plt.title('Customized Scatter Plot - how2matplotlib.com')
plt.xlabel('X-axis')
plt.ylabel('Y-axis')
plt.axhline(y=0, color='k', linestyle='--')
plt.axvline(x=0, color='k', linestyle='--')
plt.grid(True)
plt.show()
Output:
在这个例子中,我们使用c
参数设置点的颜色,s
参数设置点的大小,alpha
参数调整透明度。cmap
参数指定了颜色映射。
3.2 添加图例
当散点图包含多个数据系列时,添加图例非常有用:
import matplotlib.pyplot as plt
import numpy as np
x1 = np.random.uniform(-5, 5, 50)
y1 = np.random.uniform(-5, 5, 50)
x2 = np.random.uniform(-5, 5, 50)
y2 = np.random.uniform(-5, 5, 50)
plt.figure(figsize=(10, 8))
plt.scatter(x1, y1, c='blue', label='Series 1')
plt.scatter(x2, y2, c='red', label='Series 2')
plt.legend()
plt.title('Scatter Plot with Legend - how2matplotlib.com')
plt.xlabel('X-axis')
plt.ylabel('Y-axis')
plt.axhline(y=0, color='k', linestyle='--')
plt.axvline(x=0, color='k', linestyle='--')
plt.grid(True)
plt.show()
Output:
这个例子展示了如何为多个数据系列添加图例。
4. 添加文本注释
在散点图中添加文本注释可以帮助突出显示特定的数据点或区域:
import matplotlib.pyplot as plt
import numpy as np
x = np.random.uniform(-5, 5, 100)
y = np.random.uniform(-5, 5, 100)
plt.figure(figsize=(10, 8))
plt.scatter(x, y)
plt.annotate('Interesting Point', xy=(2, 2), xytext=(3, 3),
arrowprops=dict(facecolor='black', shrink=0.05))
plt.title('Scatter Plot with Annotation - how2matplotlib.com')
plt.xlabel('X-axis')
plt.ylabel('Y-axis')
plt.axhline(y=0, color='k', linestyle='--')
plt.axvline(x=0, color='k', linestyle='--')
plt.grid(True)
plt.show()
Output:
plt.annotate()
函数用于添加带箭头的文本注释。
5. 设置坐标轴范围
有时我们需要手动设置坐标轴的范围,以确保所有数据点都能被正确显示:
import matplotlib.pyplot as plt
import numpy as np
x = np.random.uniform(-10, 10, 100)
y = np.random.uniform(-10, 10, 100)
plt.figure(figsize=(10, 8))
plt.scatter(x, y)
plt.xlim(-12, 12)
plt.ylim(-12, 12)
plt.title('Scatter Plot with Custom Axis Range - how2matplotlib.com')
plt.xlabel('X-axis')
plt.ylabel('Y-axis')
plt.axhline(y=0, color='k', linestyle='--')
plt.axvline(x=0, color='k', linestyle='--')
plt.grid(True)
plt.show()
Output:
plt.xlim()
和plt.ylim()
函数用于设置x轴和y轴的范围。
6. 添加趋势线
在散点图中添加趋势线可以帮助我们更好地理解数据的整体趋势:
import matplotlib.pyplot as plt
import numpy as np
x = np.random.uniform(-5, 5, 100)
y = 2 * x + np.random.normal(0, 2, 100)
plt.figure(figsize=(10, 8))
plt.scatter(x, y)
z = np.polyfit(x, y, 1)
p = np.poly1d(z)
plt.plot(x, p(x), "r--")
plt.title('Scatter Plot with Trend Line - how2matplotlib.com')
plt.xlabel('X-axis')
plt.ylabel('Y-axis')
plt.axhline(y=0, color='k', linestyle='--')
plt.axvline(x=0, color='k', linestyle='--')
plt.grid(True)
plt.show()
Output:
这个例子使用np.polyfit()
和np.poly1d()
函数计算并绘制了一条线性趋势线。
7. 使用不同的标记样式
Matplotlib提供了多种标记样式,可以用来区分不同的数据系列:
import matplotlib.pyplot as plt
import numpy as np
x1 = np.random.uniform(-5, 5, 50)
y1 = np.random.uniform(-5, 5, 50)
x2 = np.random.uniform(-5, 5, 50)
y2 = np.random.uniform(-5, 5, 50)
plt.figure(figsize=(10, 8))
plt.scatter(x1, y1, marker='o', label='Series 1')
plt.scatter(x2, y2, marker='^', label='Series 2')
plt.legend()
plt.title('Scatter Plot with Different Markers - how2matplotlib.com')
plt.xlabel('X-axis')
plt.ylabel('Y-axis')
plt.axhline(y=0, color='k', linestyle='--')
plt.axvline(x=0, color='k', linestyle='--')
plt.grid(True)
plt.show()
Output:
在这个例子中,我们使用了圆形(‘o’)和三角形(‘^’)标记来区分两个数据系列。
8. 添加颜色条
当使用颜色来表示第三个维度的数据时,添加颜色条可以帮助解释颜色的含义:
import matplotlib.pyplot as plt
import numpy as np
x = np.random.uniform(-5, 5, 100)
y = np.random.uniform(-5, 5, 100)
z = x**2 + y**2
plt.figure(figsize=(10, 8))
scatter = plt.scatter(x, y, c=z, cmap='viridis')
plt.colorbar(scatter, label='Z Value')
plt.title('Scatter Plot with Colorbar - how2matplotlib.com')
plt.xlabel('X-axis')
plt.ylabel('Y-axis')
plt.axhline(y=0, color='k', linestyle='--')
plt.axvline(x=0, color='k', linestyle='--')
plt.grid(True)
plt.show()
Output:
这个例子使用点的颜色来表示z值,并添加了一个颜色条来解释颜色的含义。
9. 使用子图
当我们需要在同一个图形中比较多个散点图时,可以使用子图:
import matplotlib.pyplot as plt
import numpy as np
x1 = np.random.uniform(-5, 5, 100)
y1 = np.random.uniform(-5, 5, 100)
x2 = np.random.uniform(-5, 5, 100)
y2 = np.random.uniform(-5, 5, 100)
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(15, 6))
ax1.scatter(x1, y1)
ax1.set_title('Subplot 1 - how2matplotlib.com')
ax1.axhline(y=0, color='k', linestyle='--')
ax1.axvline(x=0, color='k', linestyle='--')
ax2.scatter(x2, y2)
ax2.set_title('Subplot 2 - how2matplotlib.com')
ax2.axhline(y=0, color='k', linestyle='--')
ax2.axvline(x=0, color='k', linestyle='--')
plt.tight_layout()
plt.show()
Output:
这个例子创建了两个并排的散点图子图。
10. 添加误差条
在某些情况下,我们可能需要显示数据点的不确定性或误差范围:
import matplotlib.pyplot as plt
import numpy as np
x = np.random.uniform(-5, 5, 20)
y = np.random.uniform(-5, 5, 20)
xerr = np.random.uniform(0, 0.5, 20)
yerr = np.random.uniform(0, 0.5, 20)
plt.figure(figsize=(10, 8))
plt.errorbar(x, y, xerr=xerr, yerr=yerr, fmt='o')
plt.title('Scatter Plot with Error Bars - how2matplotlib.com')
plt.xlabel('X-axis')
plt.ylabel('Y-axis')
plt.axhline(y=0, color='k', linestyle='--')
plt.axvline(x=0, color='k', linestyle='--')
plt.grid(True)
plt.show()
Output:
plt.errorbar()
函数用于创建带有误差条的散点图。
11. 使用不同的点大小表示权重
点的大小可以用来表示数据点的权重或重要性:
import matplotlib.pyplot as plt
import numpy as np
x = np.random.uniform(-5, 5, 50)
y = np.random.uniform(-5, 5, 50)
weights = np.random.uniform(10, 100, 50)
plt.figure(figsize=(10, 8))
plt.scatter(x, y, s=weights, alpha=0.5)
plt.title('Scatter Plot with Weighted Points - how2matplotlib.com')
plt.xlabel('X-axis')
plt.ylabel('Y-axis')
plt.axhline(y=0, color='k', linestyle='--')
plt.axvline(x=0, color='k', linestyle='--')
plt.grid(True)
plt.show()
Output:
在这个例子中,点的大小由weights
数组决定。
12. 添加边界框
有时我们可能想要突出显示散点图的特定区域:
import matplotlib.pyplot as plt
import numpy as np
x = np.random.uniform(-5, 5, 100)
y = np.random.uniform(-5, 5, 100)
plt.figure(figsize=(10, 8))
plt.scatter(x, y)
plt.axhline(y=0, color='k', linestyle='--')
plt.axvline(x=0, color='k', linestyle='--')
plt.axvspan(-2, 2, -2, 2, alpha=0.2, color='red')
plt.title('Scatter Plot with Bounding Box - how2matplotlib.com')
plt.xlabel('X-axis')
plt.ylabel('Y-axis')
plt.grid(True)
plt.show()
Output:
plt.axvspan()
函数用于创建一个矩形区域来突出显示特定的数据范围。
13. 使用3D散点图
对于三维数据,我们可以创建3D散点图:
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
import numpy as np
fig = plt.figure(figsize=(10, 8))
ax = fig.add_subplot(111, projection='3d')
x = np.random.uniform(-5, 5, 100)
y = np.random.uniform(-5, 5, 100)
z = np.random.uniform(-5, 5, 100)
ax.scatter(x, y, z)
ax.set_xlabel('X-axis')
ax.set_ylabel('Y-axis')
ax.set_zlabel('Z-axis')
ax.set_title('3D Scatter Plot - how2matplotlib.com')
plt.show()
Output:
这个例子使用mpl_toolkits.mplot3d
模块创建了一个3D散点图。
14. 使用颜色映射表示密度
我们可以使用颜色来表示数据点的密度:
import matplotlib.pyplot as plt
import numpy as np
from scipy.stats import gaussian_kde
x = np.random.normal(0, 1, 1000)
y = x * 0.5 + np.random.normal(0, 1, 1000)
xy = np.vstack([x,y])
z = gaussian_kde(xy)(xy)
plt.figure(figsize=(10, 8))
plt.scatter(x, y, c=z, s=50, cmap='viridis')
plt.colorbar(label='Density')
plt.title('Scatter Plot with Density Coloring - how2matplotlib.com')
plt.xlabel('X-axis')
plt.ylabel('Y-axis')
plt.axhline(y=0, color='k', linestyle='--')
plt.axvline(x=0, color='k', linestyle='--')
plt.grid(True)
plt.show()
Output:
这个例子使用scipy.stats.gaussian_kde
函数计算点的密度,并用颜色表示。
15. 添加等高线
在散点图上添加等高线可以帮助我们更好地理解数据的分布:
import matplotlib.pyplot as plt
import numpy as np
from scipy.stats import gaussian_kde
x = np.random.normal(0, 1, 1000)
y = x * 0.5 + np.random.normal(0, 1, 1000)
xy = np.vstack([x,y])
z = gaussian_kde(xy)(xy)
plt.figure(figsize=(10, 8))
plt.scatter(x, y, c=z, s=50, cmap='viridis')
plt.colorbar(label='Density')
# 添加等高线
xi, yi = np.mgrid[x.min():x.max():100j, y.min():y.max():100j]
zi = gaussian_kde(xy)(np.vstack([xi.flatten(), yi.flatten()]))
plt.contour(xi, yi, zi.reshape(xi.shape), colors='k', alpha=0.5)
plt.title('Scatter Plot with Contours - how2matplotlib.com')
plt.xlabel('X-axis')
plt.ylabel('Y-axis')
plt.axhline(y=0, color='k', linestyle='--')
plt.axvline(x=0, color='k', linestyle='--')
plt.grid(True)
plt.show()
Output:
这个例子在散点图上添加了密度等高线。
16. 使用不同形状的标记
我们可以使用不同形状的标记来区分不同类别的数据:
import matplotlib.pyplot as plt
import numpy as np
x1 = np.random.uniform(-5, 5, 50)
y1 = np.random.uniform(-5, 5, 50)
x2 = np.random.uniform(-5, 5, 50)
y2 = np.random.uniform(-5, 5, 50)
x3 = np.random.uniform(-5, 5, 50)
y3 = np.random.uniform(-5, 5, 50)
plt.figure(figsize=(10, 8))
plt.scatter(x1, y1, marker='o', label='Class 1')
plt.scatter(x2, y2, marker='^', label='Class 2')
plt.scatter(x3, y3, marker='s', label='Class 3')
plt.legend()
plt.title('Scatter Plot with Different Marker Shapes - how2matplotlib.com')
plt.xlabel('X-axis')
plt.ylabel('Y-axis')
plt.axhline(y=0, color='k', linestyle='--')
plt.axvline(x=0, color='k', linestyle='--')
plt.grid(True)
plt.show()
Output:
这个例子使用圆形、三角形和正方形标记来表示三个不同的类别。
17. 添加文本标签
我们可以为散点图中的特定点添加文本标签:
import matplotlib.pyplot as plt
import numpy as np
x = np.random.uniform(-5, 5, 20)
y = np.random.uniform(-5, 5, 20)
labels = [f'Point {i+1}' for i in range(20)]
plt.figure(figsize=(10, 8))
plt.scatter(x, y)
for i, label in enumerate(labels):
plt.annotate(label, (x[i], y[i]), xytext=(5, 5), textcoords='offset points')
plt.title('Scatter Plot with Text Labels - how2matplotlib.com')
plt.xlabel('X-axis')
plt.ylabel('Y-axis')
plt.axhline(y=0, color='k', linestyle='--')
plt.axvline(x=0, color='k', linestyle='--')
plt.grid(True)
plt.show()
Output:
这个例子为每个数据点添加了一个文本标签。
18. 使用渐变色
我们可以使用渐变色来表示数据点的某种属性:
import matplotlib.pyplot as plt
import numpy as np
x = np.random.uniform(-5, 5, 100)
y = np.random.uniform(-5, 5, 100)
colors = np.linspace(0, 1, 100)
plt.figure(figsize=(10, 8))
scatter = plt.scatter(x, y, c=colors, cmap='coolwarm')
plt.colorbar(scatter, label='Color Value')
plt.title('Scatter Plot with Gradient Colors - how2matplotlib.com')
plt.xlabel('X-axis')
plt.ylabel('Y-axis')
plt.axhline(y=0, color='k', linestyle='--')
plt.axvline(x=0, color='k', linestyle='--')
plt.grid(True)
plt.show()
Output:
这个例子使用了从蓝色到红色的渐变色来表示数据点的某种属性。
19. 添加趋势线和置信区间
我们可以在散点图上添加趋势线和置信区间:
import matplotlib.pyplot as plt
import numpy as np
from scipy import stats
x = np.random.uniform(-5, 5, 100)
y = 2 * x + np.random.normal(0, 2, 100)
plt.figure(figsize=(10, 8))
plt.scatter(x, y)
# 添加趋势线
slope, intercept, r_value, p_value, std_err = stats.linregress(x, y)
line = slope * x + intercept
plt.plot(x, line, color='r', label='Trend line')
# 添加置信区间
plt.fill_between(x, line - std_err, line + std_err, color='gray', alpha=0.2, label='Confidence interval')
plt.legend()
plt.title('Scatter Plot with Trend Line and Confidence Interval - how2matplotlib.com')
plt.xlabel('X-axis')
plt.ylabel('Y-axis')
plt.axhline(y=0, color='k', linestyle='--')
plt.axvline(x=0, color='k', linestyle='--')
plt.grid(True)
plt.show()
Output:
这个例子添加了一条趋势线和相应的置信区间。
20. 使用气泡图
气泡图是散点图的一种变体,其中点的大小表示第三个变量:
import matplotlib.pyplot as plt
import numpy as np
x = np.random.uniform(-5, 5, 50)
y = np.random.uniform(-5, 5, 50)
sizes = np.random.uniform(20, 500, 50)
colors = np.random.uniform(0, 1, 50)
plt.figure(figsize=(10, 8))
plt.scatter(x, y, s=sizes, c=colors, alpha=0.5, cmap='viridis')
plt.colorbar(label='Color Value')
plt.title('Bubble Chart - how2matplotlib.com')
plt.xlabel('X-axis')
plt.ylabel('Y-axis')
plt.axhline(y=0, color='k', linestyle='--')
plt.axvline(x=0, color='k', linestyle='--')
plt.grid(True)
plt.show()
Output:
在这个气泡图中,点的大小表示一个变量,颜色表示另一个变量。
总结:
本文详细介绍了如何使用Matplotlib创建包含正负轴的散点图,并探讨了多种自定义和增强散点图的方法。我们学习了如何调整点的大小、颜色和形状,添加图例和注释,设置坐标轴范围,添加趋势线和误差条,以及创建3D散点图等高级技巧。这些技术可以帮助我们更有效地可视化和分析数据,特别是在处理跨越原点的数据时。通过掌握这些技巧,我们可以创建更加丰富、信息量更大的散点图,从而更好地理解和展示数据中的模式和关系。