Matplotlib绘制np.array数据集分组堆叠柱状图及图例颜色问题问询
问题1:子图未按预期生成的原因及解决
你两次调用plt.subplot()时未指定子图的网格位置参数,默认会复用1行1列的第1个坐标轴对象,因此两次绘图内容会重叠在同一个区域,不会生成两个独立子图。
如果你的需求是生成两个独立排列的子图,只需要在创建时指定位置参数即可,比如上下排列的两个子图可以写为:
import numpy as np import matplotlib.pyplot as plt data = np.array([[20, 40, 30, 20], [20, 40, 30, 20], [20, 40, 30, 20]]) data2 = np.array([[90, 10], [90, 10], [90, 10]]) x = ['2020', '2025', '2030'] x_idx = np.arange(len(x)) fig = plt.figure(figsize=(10,5)) # 2行1列第1个坐标轴 ax1 = plt.subplot(211) for i in range(data.shape[1]): bottom = np.sum(data[:,0:i], axis=1) erzeugung = ax1.bar(x, data[:,i], bottom=bottom, width=0.3, label=f"label {i}") ax1.bar_label(erzeugung, padding=3) # 2行1列第2个坐标轴 ax2 = plt.subplot(212) for i in range(data2.shape[1]): bottom = np.sum(data2[:,0:i], axis=1) verbrauch = ax2.bar(x, data2[:,i], bottom=bottom, width=0.3, label=f"label {i}") ax2.bar_label(verbrauch, padding=3) fig.tight_layout() plt.show()
如果你要的是分组堆叠柱状图(即每个年份下并排显示两个堆叠柱),不需要创建两个子图,只需要在同一个坐标轴上偏移第二个数据集的x位置即可,示例如下:
import numpy as np import matplotlib.pyplot as plt data = np.array([[20, 40, 30, 20], [20, 40, 30, 20], [20, 40, 30, 20]]) data2 = np.array([[90, 10], [90, 10], [90, 10]]) x = ['2020', '2025', '2030'] x_idx = np.arange(len(x)) width = 0.35 fig, ax = plt.subplots(figsize=(10,5)) # 绘制第一组堆叠柱 for i in range(data.shape[1]): bottom = np.sum(data[:,0:i], axis=1) ax.bar(x_idx - width/2, data[:,i], bottom=bottom, width=width, label=f"dataset1 label {i}") # 绘制第二组堆叠柱,位置右移避免重叠 for i in range(data2.shape[1]): bottom = np.sum(data2[:,0:i], axis=1) ax.bar(x_idx + width/2, data2[:,i], bottom=bottom, width=width, label=f"dataset2 label {i}") ax.set_xticks(x_idx) ax.set_xticklabels(x) ax.legend(bbox_to_anchor=(1.1, 1)) fig.tight_layout() plt.show()
问题2:图例颜色重复的解决
matplotlib默认使用的tab10定性色盘仅包含10种不重复颜色,当标签数量超过10个时就会循环复用颜色,出现你遇到的重复问题。
切换为颜色数量更多的色盘即可解决,比如tab20色盘包含20种不重复颜色,完全可以覆盖14个标签的需求,只需要在绘图前添加一行配置:
plt.rcParams['axes.prop_cycle'] = plt.cycler('color', plt.cm.tab20.colors)
如果你需要更多自定义颜色,也可以自己定义颜色列表传入,比如:
custom_colors = ['#FF5733', '#33FF57', '#3357FF', '#F333FF', '#FF33A6', '#33FFF6', '#FF8C33', '#8C33FF', '#33FF8C', '#FF3333', '#3333FF', '#FFFF33', '#33FFFF', '#FF33FF'] plt.rcParams['axes.prop_cycle'] = plt.cycler('color', custom_colors)
内容的提问来源于stack exchange,提问作者Elias
相关产品推荐
相关产品推荐

