TIME:2022-04-25

最近毕业设计需要给我的仿真结果画图,想来以前用了这么久的matplotlib却一直没有归纳各种画图方法,在此进行归纳,方便以后参考,直接CV来用。

绘制双纵轴的折线图

基本思路:使用figure制作图纸,对图纸使用插入子图add_subplot,使用twinx方法获取相同子图。

得到双轴图纸,分别为ax1轴与ax2轴。

from matplotlib import pyplot as plt
import numpy
import pandas
import const

# -------------读取数据文件参数设置-----------------------
data_file = const.loadNaturalEnergyFile
timeX = [i for i in range(24)]

# -------------载入数据转化为numpy形式-----------------------
df = pandas.read_excel(data_file, skiprows=0, index_col=0)
nd = numpy.array(df)

# -------------图表参数-----------------------
row_index = 1
figure_title = '广州地区平均风速与太阳辐射照度'
x_label = 'Time'
y_label = 'value'

# -------------字体设置-----------------------
plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号
font_size = 20

# -------------制作图纸-----------------------
fig = plt.figure(figsize=(10, 5))
# -------------绘图-----------------------
ax1 = fig.add_subplot(111)
ax1.plot(timeX, nd[0], label='平均风速', color='#4A7EBB', marker='d', alpha=0.7)
ax1.xaxis.set_ticks(numpy.arange(min(timeX), max(timeX)+1, 1.0), rotation=30)
ax2 = ax1.twinx()
ax2.plot(timeX, nd[1], label='太阳辐射照度', color='orange', marker='o', alpha=0.7)
ax2.xaxis.set_ticks(numpy.arange(min(timeX), max(timeX)+1, 1.0), rotation=30)
ax1.set_ylabel('平均风速 v(m/s)', fontsize=font_size)
ax2.set_ylabel('太阳辐射照度 I(kW/m$^{2}$)', fontsize=font_size)
legend1 = ax1.legend(loc=(.02, .94), fontsize=13, shadow=False)
legend2 = ax2.legend(loc=(.02, .89), fontsize=13, shadow=False)
# -------------设置图表标题-----------------------
plt.title(figure_title, fontsize=font_size)
# -------------显示绘制图片-----------------------
plt.show()
  • 通过xaxis.set_ticks设置x坐标的刻度。
  • 通过set_ylabel对两个不同的轴设置轴标签。
  • plot的alpha属性可以设置绘制折线的透明度。

绘制显示值的柱状图

使用plt.text来显示数值,使用plt.bar来画柱状图。

参考:

【Python】plt.bar绘制柱状图参数详解_Asher117的博客-CSDN博客_plt.bar参数

python画柱状图并数值显示_总裁余(余登武)的博客-CSDN博客_python柱状图显示数值

我的代码如下:

from matplotlib import pyplot as plt
from matplotlib import cm, colors
import numpy
import pandas

# -------------读取数据文件参数设置-----------------------
data_file = r'E:\本科毕业设计(园区综合能源规划算法与模型)\毕业设计论文\算例分析结果\场景4\best\operation.xls'
timeX = [i for i in range(24)]
# -------------载入数据转化为numpy形式-----------------------
df = pandas.read_excel(data_file, skiprows=0, index_col=0)
nd = numpy.array(df)
print(nd)
# -------------图表参数-----------------------
figure_title = '场景4逐时段光伏阵列出力情况'
x_label = 'Time(h)'
y_label = 'Power(kW)'
# -------------字体设置-----------------------
plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号
font_size = 20
# -------------制作图纸-----------------------
fig = plt.figure(figsize=(10, 5))
plt.xlabel(x_label, fontsize=font_size)
plt.ylabel(y_label, fontsize=font_size)
# -------------绘图-----------------------
plt.bar(timeX, nd[1], color='orange', alpha=0.9)
# -------------柱子上的数字显示-----------------------
for a, b in zip(timeX, nd[1]):  # plt.text(字的x坐标, 字的y坐标, string, 对齐方式, 显示位置, 字体大小)
    if b > 0:
        va = 'bottom'
        delta = 10
    else:
        va = 'top'
        delta = -10
    if b < 1e-3: continue
    plt.text(a, b + delta, '%.2f' % b, ha='center', va=va, fontsize=10)
# -------------设置x轴的刻度-----------------------
plt.xticks(numpy.arange(min(timeX), max(timeX) + 1, 1.0))
# -------------设置图表说明-----------------------
plt.legend(['光伏阵列输出功率'])
# -------------设置图表标题-----------------------
plt.title(figure_title, fontsize=font_size)
# -------------显示绘制图片-----------------------
plt.show()

绘制渐变柱状图

具体参考如下:

matplotlib官方示例渐变柱状图详解_小白爱写代码的博客-CSDN博客

色彩映射表参考 — Matplotlib 3.5.1 文档

我的代码如下:

import matplotlib.pyplot as plt
import numpy
import pandas
import const

# df = pandas.read_excel(const.loadParamFile, skiprows=0, index_col=0)
# nd = numpy.array(df)
# nd = nd[:3]
data_file = r'E:\本科毕业设计(园区综合能源规划算法与模型)\毕业设计论文\算例分析结果\场景4\best\operation.xls'
df = pandas.read_excel(data_file, skiprows=0, index_col=0)
nd = numpy.array(df)


def gradient_image(ax, extent, direction=0, cmap_range=(0, 1), **kwargs):
    phi = direction * numpy.pi / 2
    v = numpy.array([numpy.cos(phi), numpy.sin(phi)])
    X = numpy.array([[v @ [1, 0], v @ [1, 1]],
                     [v @ [0, 0], v @ [0, 1]]])
    a, b = cmap_range
    X = a + (b - a) / X.max() * X
    interpolation = 'bicubic'
    im = ax.imshow(X, extent=extent, interpolation=interpolation,
                   vmin=0, vmax=1, **kwargs)
    return im


def gradient_bar(ax, x, y, cmap=plt.cm.Blues_r, width=0.5, bottom=0):
    for left, top in zip(x, y):
        right = left + width
        # if top < 0:
        #     bottom = top
        #     top = 0
        # print(left, right, bottom, top)
        gradient_image(ax, extent=(left, right, bottom, top),
                       cmap=cmap, cmap_range=(0, 0.8))


bar_width = 0.8
x_min = -1.5 * bar_width
x_max = 23 + 1.5 * bar_width
y_min = min(nd[-2]) - 50
y_max = max(nd[-2]) + 50
x_lim = [x_min, x_max]
y_lim = [y_min, y_max]

fig, ax = plt.subplots()
ax.set(xlim=x_lim, ylim=y_lim, autoscale_on=False)

x = numpy.arange(24) - bar_width / 2

gradient_bar(ax, x, nd[-2], cmap=plt.cm.GnBu, width=bar_width)
# gradient_bar(ax, x + bar_width, nd[1], cmap=plt.cm.plasma, width=bar_width)
# gradient_bar(ax, x - bar_width, nd[2], cmap=plt.cm.Blues, width=bar_width)
ax.set_aspect('auto')
plt.show()

注意,注释部分是一开始画渐变色并列柱状图的代码,但是配色找不到好看的,所有最后没有使用。

cmap参数输入对应的matplotlib色条映射名称就行。

cmap_range参数的改变对美观和配色相当重要!

绘制堆叠柱状图

使用bar画柱状图,设置每次同一x值下的bottom参数不同,从而实现堆叠。

我的代码如下:

from matplotlib import pyplot as plt
from matplotlib import cm, colors
import numpy
import pandas

# -------------读取数据文件参数设置-----------------------
data_file = r'E:\本科毕业设计(园区综合能源规划算法与模型)\毕业设计论文\算例分析结果\场景4\best\operation.xls'
timeX = [i for i in range(24)]

# -------------载入数据转化为numpy形式-----------------------
df = pandas.read_excel(data_file, skiprows=0, index_col=0)
nd = numpy.array(df)
print(nd)

# -------------图表参数-----------------------
figure_title = '场景4逐时段各设备供热出力情况'
x_label = 'Time(h)'
y_label = 'Power(kW)'

# -------------字体设置-----------------------
plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号
font_size = 20

# -------------制作图纸-----------------------
fig = plt.figure(figsize=(10, 5))
plt.xlabel(x_label, fontsize=font_size)
plt.ylabel(y_label, fontsize=font_size)
# -------------绘图-----------------------
colorsList = ['#F2B825',  '#88B421', '#199FE0']
# colorsList = ['purple', '#F2B825', '#F38562',  '#D4C114', '#88B421', '#199FE0']
# colorsList = ['#FD6D5A', '#FEB40B', '#6DC354', '#994487', '#518CD8', '#443295']
for t in timeX:
    bottom1, bottom2 = 0, 0
    for index, i in enumerate([4, 8, 10]):
        if nd[i][t] > 0:
            plt.bar(t, nd[i][t], color=colorsList[index], bottom=bottom1, edgecolor='black', alpha=0.8)
            bottom1 += nd[i][t]
        else:
            plt.bar(t, nd[i][t], color=colorsList[index], bottom=bottom2, edgecolor='black', alpha=0.8)
            bottom2 += nd[i][t]
# -------------画零值线-----------------------
zero_value = [i for i in range(-1, 25)]
plt.plot(zero_value, [0 for i in zero_value], color='black', alpha=1)
# -------------设置x轴刻度-----------------------
plt.xticks(numpy.arange(min(timeX), max(timeX) + 1, 1.0))
plt.legend(['零值线', '燃气锅炉输出功率', '热储能系统充放热功率', '购热功率'])
# -------------设置图表标题-----------------------
plt.title(figure_title, fontsize=font_size)
# -------------显示绘制图片-----------------------
plt.show()
  • 使用edgecolor参数画出柱状图的边框(可以极大提高美观)
  • 使用alpha参数设置柱状图填充色的透明度
  • 注意对于大于0和小于0的值,不能用同一bottom值堆叠(分正值bottom值与负值bottom值)
  • 建议配色:[‘FEB40B’, ‘6DC354’, ‘994487’, ‘518CD8’, ‘443295’](未加#号码)

配色方案参考:

【2.1.1 颜色模板】科研绘图必备的60套颜色模板 - 知乎 (zhihu.com)

matlab画图有什么好的配色方案? - 知乎 (zhihu.com)

Matlab画堆叠柱状图(颜色设置,x轴外部标注,y轴标注,颜色设置)_你见我U盘没的博客-CSDN博客_堆积柱形图配色

Logo

鸿蒙生态一站式服务平台。

更多推荐