import random
from matplotlib import pyplot as plt
from mpl_toolkits.axisartist.parasite_axes import HostAxes, ParasiteAxes
def plt_price(x: dict,
y: Union[dict, List[dict]],
size: Tuple[int, int],
offset: int = 50):
"""
根据传入的数据进行折线图的绘制
:param x: x轴坐标数据
x = dict(
data=, # 数据集
name= # x轴名称
xlim=(1, 100) # x轴数据范围
)
:param y: y轴需要绘制的数据
y = dict(
data=, # 数据集
name=, # y轴名称
line="r-", # 绘制线条及颜色,r:red, -:直线,其余样式自行网查
label=
# 默认颜色,用于当输入数据未确定color时,选择随机color
base_color = ["black", "red", "blue", "pink", "yellow"]
# 创建figure,并设置大小为size
figure = plt.figure(figsize=size)
# 创建Axes层上的主轴,后续寄生轴ParasiteAxes操作都在此基础上操作
# 而此Axes层是基于之前创建的Figure层之上
# 第二个参数说明,分别对应:left, bottom, width, height
axes_host = HostAxes(figure, [0.05, 0.1, 0.8, 0.9])
# 获取主轴对应的数据data和标签label
x_data = x["data"]
x_label = x.get("label", "")
# 在主轴上设置x标签
axes_host.set_xlabel(x_label)
# 设置主轴的right和top为不可见,及没有刻度
axes_host.axis["right"].set_visible(False)
axes_host.axis["top"].set_visible(False)
# 设置主轴的x轴数据限制
# axes_host.set_xlim(0, 2)
# 开始遍历需要绘制的数据
for y_ in y:
# 获取需要绘制的数据data, 标签label, 颜色color以及数据限制limit
y_data = y_["data"]
y_label = y_.get("label")
y_color = y_.get("color", random.choice(base_color))
y_limit = y_.get("limit", False)
# 第一个数据默认使用主轴上显示
if y.index(y_) == 0:
# axes_host.set_ylim(0, 1000)
# 获取当前需要显示的数据的y轴label
axes_host.set_ylabel(y_label)
# 在主轴上绘制数据
axes_host.plot(x_data, y_data, label=y_label, color=y_color)
# 从第二个需要显示的数据开始,需要使用寄生轴ParasiteAxes来展示,
elif y.index(y_) > 0:
# 新建一个寄生轴ParasiteAxes,寄生与主轴HostAxes, 同时寄生轴的x轴使用主轴的x轴
axes_parasite = ParasiteAxes(axes_host, sharex=axes_host)
# 在现有主轴axes_host的寄生轴中添加新建的寄生轴axes_parasite
axes_host.parasites.append(axes_parasite)
# 寄生轴设置
# 设置y轴标签
axes_parasite.set_ylabel(y_label)
# 设置刻度显示
axes_parasite.axis["right"].major_ticklabels.set_visible(True)
# 设置标签显示
axes_parasite.axis["right"].label.set_visible(True)
# 第一个数据显示在主轴,第二个直接将y轴展示在右侧,以此类推,第三个之后(即y.index(y_) > 1)的y轴显示在第二个y轴的右侧
if y.index(y_) > 1:
# 获取当前数据的index
y_index = y.index(y_)
# 加载一个固定的y轴
load_axisline = axes_parasite.get_grid_helper().new_fixed_axis
# 在寄生轴axes_parasite的右侧按照index的顺序添加y轴,offset设置相邻两个y轴的间距
axes_parasite.axis["right{0}".format(y_index)] = load_axisline(loc="right", axes=axes_parasite, offset=(offset * (y_index - 1), 0))
# 如果是第二个数据则之间显示在需要绘制图表的右侧
else:
# 将此时的index至空,因为需要输入的右侧的字符串顺序为["right", "right2", "right3", ...]
y_index = ""
# 设置添加的y轴为可见
axes_parasite.axis["right"].set_visible(True)
# 在新建的寄生轴上绘制数据
axes_parasite.plot(x_data, y_data, label=y_label, color=y_color)
# 为当前数据的label, major_ticks, major_ticklabels, line设置为跟坐标轴一样的颜色
axes_parasite.axis["right{0}".format(y_index)].label.set_color(y_color)
axes_parasite.axis["right{0}".format(y_index)].major_ticks.set_color(y_color)
axes_parasite.axis["right{0}".format(y_index)].major_ticklabels.set_color(y_color)
axes_parasite.axis["right{0}".format(y_index)].line.set_color(y_color)
# 设置y轴的数据限制
if y_limit:
axes_parasite.set_ylim(0, 4)
# 在figure层上添加当前的Aexs层
figure.add_axes(axes_host)
# 在当前的Aexs层上显示标签提示
axes_host.legend()
# 开始绘制数据
plt.show()
for name, groups in data_1_groups_copy.items():
_price = dict(data=[data_1_copy.loc[index, "AnchorPrice"] for index in groups], name="单价", color="black", label="单价", title="商品顺序与单价关系曲线")
_sales_num = dict(data=[data_1_copy.loc[index, "SalesNum"] for index in groups], name="销售量", color="blue", label="销售量", title="商品顺序与销售量关系曲线")
_sales_count = dict(data=[data_1_copy.loc[index, "SalesCount"] for index in groups], name="销售总金额", color="red", label="销售总金额", title="商品顺序与销售总金额曲线")
_mean_price = dict(data=[108 for index in groups], name="带货价格108", color="pink", label="带货价108")
_x = dict(data=[data_1_copy.loc[index, "GoodsIndex"] for index in groups], name="商品顺序", label="{0}-商品顺序".format(name))
# 开始绘制
plt_price(x=_x, y=[_price, _sales_num, _sales_count, _mean_price], size=(16, 4), subplot=(2, 2))
Done, 2021年2月5日14:16:58, by lpliner.