- 趋势分析:折线图
- 静态比较:条形图
- 分布分析:箱线图
- 离散情况:散点图
import matplotlib.pylab as plt
from abc import ABC, abstractmethod
import seaborn as sns
import pandas as pd
import plotly.graph_objects as go
import plotly.io as pio
import altair as alt
from bokeh.plotting import figure, output_file, show
from bokeh.io import output_file, show
from bokeh.palettes import Category20c
from bokeh.plotting import figure, show
from bokeh.transform import cumsum
from math import pi
import numpy as npclass PlotStrategy(ABC):# 抽象类:强制子类实现此方法@abstractmethoddef plot(self, x_data, y_data, desc):passclass LineMulPlotStrategy(PlotStrategy):def plot(self, x_data, y_data, desc):print('折线图')plt.clf() # 清除当前图形内容arr_data = [d[list(d.keys())[0]] for d in y_data] # 提取数据arr_key = [list(d.keys())[0] for d in y_data]plt.plot(x_data, arr_data[0], label=arr_key[0])plt.plot(x_data, arr_data[1], label=arr_key[1])plt.xlabel(desc[1])plt.ylabel(desc[2])plt.title(desc[0])plt.legend()# plt.show()plt.savefig('./lineMul.png')class BarMulPlotStrategy(PlotStrategy):def plot(self, x_data, y_data, desc):print('柱状图')plt.clf() # 清除当前图形内容arr_data = [d[list(d.keys())[0]] for d in y_data] # 提取数据arr_key = [list(d.keys())[0] for d in y_data]bar_width = 0.35 # 条形宽度x_offset = 0.2 # 每个条形图的水平偏移量# 绘制第一个条形图# np.arange() 函数的作用是生成一个等差序列的一维数组。# 如果 x_data 是一个有 5 个元素的列表,那么 np.arange(len(x_data)) 将生成一个包含 0、1、2、3、4 的整数数组plt.bar(np.arange(len(x_data)) - x_offset, arr_data[0], width=bar_width, label=arr_key[0])# 绘制第二个条形图plt.bar(np.arange(len(x_data)) + x_offset, arr_data[1], width=bar_width, label=arr_key[1])# plt.bar(x_data, arr_data[0])# plt.bar(x_data, arr_data[1])plt.xlabel(desc[1])plt.ylabel(desc[2])plt.title(desc[0])# plt.show()plt.savefig('./BarMul.png')class BoxMulPlotStrategy(PlotStrategy):def plot(self, x_data, y_data, desc):print('箱线图')plt.clf() # 清除当前图形内容arr_data = [d[list(d.keys())[0]] for d in y_data] # 提取数据arr_key = [list(d.keys())[0] for d in y_data]plt.boxplot(arr_data, tick_labels=arr_key)plt.xlabel(desc[1])plt.ylabel(desc[2])plt.title(desc[0])# plt.show()plt.savefig('./BoxMul.png')class ScatterMulPlotStrategy(PlotStrategy):def plot(self, x_data, y_data, desc):print('散点图')plt.clf() # 清除当前图形内容arr_data = [d[list(d.keys())[0]] for d in y_data] # 提取数据arr_key = [list(d.keys())[0] for d in y_data]plt.scatter(x_data, arr_data[0], label=arr_key[0])plt.scatter(x_data, arr_data[1], label=arr_key[1])plt.xlabel(desc[1])plt.ylabel(desc[2])plt.title(desc[0])# 显示label对应的图例plt.legend()# plt.show()plt.savefig('./ScatterMul.png')# Context类持有PlotStrategy的引用。可以通过set_strategy方法动态地更改策略
class Context:def __int__(self, strategy: PlotStrategy):# _ 开头的变量,表示这是一个受保护的变量# 该变量只在类内部及其子类中使用,而不应在类外部直接访问self._strategy = strategydef set_strategy(self, strategy: PlotStrategy):self._strategy = strategydef execute_strategy(self, x_data, y_data, desc):self._strategy.plot(x_data, y_data, desc)x = ['A','B','C','D','E']
y = [{'key1':[2, 3, 6, 1, 4]},{'key2':[1, 2, 3, 4, 5]}]
desc = ['title', 'x', 'y']context = Context()context.set_strategy(LineMulPlotStrategy())
context.execute_strategy(x, y, desc)context.set_strategy(BarMulPlotStrategy())
context.execute_strategy(x, y, desc)context.set_strategy(BoxMulPlotStrategy())
context.execute_strategy(x, y, desc)context.set_strategy(ScatterMulPlotStrategy())
context.execute_strategy(x, y, desc)
折线图
柱状图
箱线图
散点图