Python绘图时【坐标轴文字相互重叠/覆盖】问题的解决方法
有时候我们使用python程序的matplotlib包,生成一些柱状图或折线图,会出现坐标文字放不下,相互覆盖的问题。(比如用下面的代码生成的图片)
import matplotlib.pyplot as plt
import textwrap
import random
# 创建示例数据
categories = [f"Category {i}" for i in range(1, 21)]
values = [random.randint(10, 100) for _ in range(20)]
# 绘制柱状图
plt.figure(figsize=(10, 5))
plt.bar(categories, values)
plt.xlabel('Categories')
plt.ylabel('Values')
plt.title('Sample Bar Chart with Overlapping Labels')
plt.show()
坐标文字相互覆盖的解决办法
为了让横坐标的文字不互相覆盖,有以下几个可能的解决办法:
1. 增加图表的宽度:
通过增加图表的宽度,可以给横坐标标签更多的空间。
比如我使用下面的代码,通过一句plt.figure(figsize=(25, 5))
,把原来的1000*500
像素的图片,调节成2500*500
的图片。宽度增加了,文字覆盖的问题就解决了
import matplotlib.pyplot as plt
import textwrap
import random
# 创建示例数据
categories = [f"Category {i}" for i in range(1, 21)]
values = [random.randint(10, 100) for _ in range(20)]
# 方法1:增加图表的宽度
plt.figure(figsize=(25, 5))
plt.bar(categories, values)
plt.xlabel('Categories')
plt.ylabel('Values')
plt.title('Sample Bar Chart with Increased Width')
plt.show()
2.旋转横坐标标签:
通过旋转横坐标标签,使其以一定角度显示,从而减少覆盖。
import matplotlib.pyplot as plt
import textwrap
import random
# 创建示例数据
categories = [f"Category {i}" for i in range(1, 21)]
values = [random.randint(10, 100) for _ in range(20)]
# 方法2:旋转横坐标标签
plt.figure(figsize=(10, 5))
plt.bar(categories, values)
plt.xticks(rotation=45, ha='right')
plt.xlabel('Categories')
plt.ylabel('Values')
plt.title('Sample Bar Chart with Rotated Labels')
plt.tight_layout()
plt.show()
方法3:使用tight_layout()
tight_layout()
函数可以自动调整子图参数,以便使子图之间和标签之间不重叠。它会根据图表的大小和子图的内容,自动调整子图的间距和位置。
plt.tight_layout(pad=1.08, h_pad=None, w_pad=None, rect=None)
参数说明
- pad:浮点数,默认值为 1.08,表示子图之间的填充大小,单位是字体大小。
- h_pad:浮点数,表示子图之间的高度填充大小,单位是字体大小。如果未指定,默认值为 pad。
- w_pad:浮点数,表示子图之间的宽度填充大小,单位是字体大小。如果未指定,默认值为 pad。
- rect:四元组,表示图表的边界(左、右、下、上),值在 [0, 1] 之间。例如,rect=[0, 0, 1, 1] 表示整个图表。
import matplotlib.pyplot as plt
import textwrap
import random
# 创建示例数据
categories = [f"Category {i}" for i in range(1, 21)]
values = [random.randint(10, 100) for _ in range(20)]
plt.figure(figsize=(10, 5))
plt.bar(categories, values)
plt.xlabel('Categories')
plt.ylabel('Values')
plt.title('Sample Bar Chart with tight_layout and subplots_adjust')
plt.tight_layout()
plt.show()
虽然嘞,我自己感觉,图片设置的过于窄的话,使用这两个函数调节的效果不好。因为它只是自动的调节图表的大小,但是如果图片本身不够大,即使图表稍微变小了,留下的位置仍然不够,仍然会让标签覆盖。所以大家可以看最下面的综合方法,可以自动+手动,解决这个问题。
方法4. 使用 textwrap 模块:对长标签进行换行处理。
可以加一句代码:wrapped_labels = [textwrap.fill(label, 5) for label in categories]
,让所有的categories
里的label
,当宽度大于5的时候,自动换行。
import matplotlib.pyplot as plt
import textwrap
import random
# 创建示例数据
categories = [f"Category {i}" for i in range(1, 21)]
values = [random.randint(10, 100) for _ in range(20)]
# 方法4:使用textwrap模块对长标签进行换行处理
wrapped_labels = [textwrap.fill(label, 5) for label in categories]
plt.figure(figsize=(10, 5))
plt.bar(wrapped_labels, values)
plt.xlabel('Categories')
plt.ylabel('Values')
plt.title('Sample Bar Chart with Wrapped Labels')
plt.tight_layout()
plt.show()
这样的方法也不错
方法5 : 综合上述方法:
import matplotlib.pyplot as plt
import textwrap
import random
# 创建示例数据
categories = [f"Category {i}" for i in range(1, 21)]
values = [random.randint(10, 100) for _ in range(20)]
# 方法1:增加图表的宽度,从1000*500变成2000*1000
fig, ax = plt.subplots(figsize=(20, 10))
# 方法4:使用textwrap模块对长标签进行换行处理
wrapped_labels = [textwrap.fill(label, 10) for label in categories]
# 绘制柱状图
ax.bar(wrapped_labels, values)
# 方法2:旋转横坐标标签
ax.set_xticklabels(wrapped_labels, rotation=45, ha='right')
# 方法3:使用tight_layout()
plt.tight_layout() # 自动调整底部间距
# 添加标签和标题
ax.set_xlabel('Categories')
ax.set_ylabel('Values')
ax.set_title('Sample Bar Chart with Combined Methods')
# 手动调整图表边距
plt.subplots_adjust(left=0.1, right=0.9, top=0.9, bottom=0.2)
# 显示图表
plt.show()
上面方法里,除了综合之前的方法,还加了一段手动调节图表间距。通过给标签留出足够的位置,让标签显示完全(看下面的代码,图表左边从画布10%处开始,图表右边从画布90%处结束。图表下边从画布10%处开始,图表上边从画布10%处开始
)
# 手动调整图表边距
plt.subplots_adjust(left=0.1, right=0.9, top=0.9, bottom=0.2)