import matplotlib.pyplot as plt
import matplotlib.patches as mpatches # 用于绘制自由色块
import matplotlib.ticker as mtick # 用于设置坐标刻度
import matplotlib.lines as mlines # 用于绘制自由形状
def box():
solidity = pd.read_excel(r"result\solidity.xlsx", sheet_name="solidity")
s = solidity.iloc[0:100,:] * -100
designed = pd.read_excel(r"result\solidity.xlsx", sheet_name="groupI",usecols=[0,1,2])
designed.loc[:, "TRoff"] = designed.loc[:, "TRoff"] * -100
designed.loc[:, "TTss"] = designed.loc[:, "TTss"] * -100
# 将数据处理为正值百分数
position = np.array(range(1, 22, 5))
RoffScatX = position
TssScatX = position + 2
# 设置散点图横坐标
# 绘制箱线图
c_list = [
"skyblue",
"steelblue",
"skyblue",
"steelblue",
"skyblue",
"steelblue",
"skyblue",
"steelblue",
"skyblue",
"steelblue",
]
# 颜色代码列表
positions = np.sort(np.concatenate([position, position + 2])).tolist()
# 箱体位置坐标
plt.figure(figsize=(8, 3.5))
f = plt.boxplot(
s, vert=True, sym="+b",
patch_artist=True,
widths=0.8, positions=positions
)
# 绘箱型图,注意此处的f
# f是一个字典,它包含了由plt.boxplot()函数返回的所有组成箱形图的元素
# 'boxes':表示箱体的Line2D对象的列表
# 因此在下方可以给对应的对象进行颜色设置
for box, c in zip(f["boxes"], c_list):
# 对箱线图设置颜色
box.set(color=c, linewidth=2)
box.set(facecolor=c)
# 绘制散点图,参数分别为
# 横坐标,纵坐标,标签,颜色,图层顺序(zorder值越大越靠上)
plt.scatter(
RoffScatX,
designed["TRoff"],
label="Designed TR Slash Rate",
c="lightgreen",
zorder=3,
)
plt.scatter(
TssScatX,
designed["TTss"],
label="Designed TSS Slash Rate",
c="orange",
zorder=3,
)
# 创建图例的代理
# 与line不同,box创建后没有相应的artist句柄,
# 因此无法直接通过legend()方法创建
# 通过创建patch和Line2D的实例,我们创建了对应的图标以及标签,
# 并在legend()方法中进行调用
skyblue_patch = mpatches.Patch(color="skyblue", label="Random TR Slash Rate")
steelblue_patch = mpatches.Patch(color="steelblue", label="Random TTS Slash Rate")
# 创建图例图形
TR_circle = mlines.Line2D(
[],
[],
color="lightgreen",
marker="o",
linestyle="None",
markersize=6,
label="Designed TR Slash Rate",
)
# 前两个空白参数表示忽略图形的位置
TSS_circle = mlines.Line2D(
[],
[],
color="orange",
marker="o",
linestyle="None",
markersize=6,
label="Designed TSS Slash Rate",
)
plt.legend(
handles=[skyblue_patch,
steelblue_patch,
TR_circle, TSS_circle], loc="best",
prop={'size': 8}
)
# 显示图例,将上文中创建的图例对象作为句柄,loc表示位置
plt.xlim(-1, 25)
# 设置x坐标的范围
plt.xlabel('Return Period')
plt.ylabel('Slash Rate')
a = plt.gca()
# 由于在前文中直接调用了plt,因此当前绘图区域没有对应的句柄
# gca()gca是"get current axes"的缩写。
# 这个函数的作用是获取当前的Axes实例。
a.yaxis.set_major_formatter(mtick.PercentFormatter())
# 将该绘图区域的y轴设置为百分数显示
xscale_ls = position + 1
# 设置x坐标标签的位置
plt.xticks(xscale_ls, y, fontsize=10)
# 设置x坐标标签的位置以及用文字进行替换,y为文字列表
plt.yticks(fontsize=10, color="#000000")
plt.savefig(r"pictures\randomSolid.png", format="png")
# format = 字段是必需的
plt.show()
# plt.savefig()应该在plt.show()之前调用。因为plt.show()可能会清空当前的图像,
# 所以如果在plt.show()之后调用plt.savefig(),可能会保存一个空白的图像3。
上面这张图片是代码运行结果,虽然我觉得配色,构图还挺好看的,但是不太符合导师要求,后来也做了很大改动,把先前的版本发在csdn上,记录一下学习过程吧。
虽然用的是.py格式的文件跑程序,但是在代码里一个个部分都还是主要通过函数结构组织起来之后通过交互式代码运行。好处是结构清晰,整个组块在交互式中轻松运行,缺点是如果没有率先进行函数定义,在代码完成后才进行定义的话,需要逐行进行缩进。
我认为这种方式和Jupyter的组块式相比,更适合编程小白。因为运行过程中后者的cell之间的逻辑是线性的,否则需要一个个运行cell,交互式中的组块运行则对代码行之间的逻辑顺序不做要求,在试错阶段,想运行那个部分就运行那个部分,可以全部运行结束得到正确结果之后再对结构进行调整,运行结果同样实时储存。对脑子不太清晰,且不求代码水平精进的编程者来说是一枚利器。
但是不知道这种交互式运行方式对运行速度和内存占用有没有什么影响,现在跑的都是小量数据,因此无法得到结论,等后续需要进行大量数据计算时再来更新,如果有知道这个问题答案的大佬看见了这篇文章也烦请赐教。