当前位置: 首页 > news >正文

Python使用策略模式实现绘图功能

策略模式(Strategy Pattern):允许定义一系列算法,将它们封装起来,使得它们可以互换。

实现绘制不同类型的图表(如折线图、柱状图和饼图)功能。

下面是一个示例,展示如何传入横坐标和纵坐标内容,然后绘制不同类型的图表。

import matplotlib.pylab as plt
from abc import ABC, abstractmethodclass PlotStrategy(ABC):# 抽象类:强制子类实现此方法@abstractmethoddef plot(self, x_data, y_data, desc):passclass LinePlotStrategy(PlotStrategy):def plot(self, x_data, y_data, desc):print('折线图')plt.plot(x_data,y_data,marker=0)plt.title(desc[0])plt.xlabel(desc[1])plt.ylabel(desc[2])plt.show()class BarPlotStrategy(PlotStrategy):def plot(self, x_data, y_data, desc):print('柱状图')plt.bar(x_data, y_data)plt.title(desc[0])plt.xlabel(desc[1])plt.ylabel(desc[2])plt.show()class PiePlotStrategy(PlotStrategy):def plot(self, x_data, y_data, desc):print('饼图')labels = x_datasizes = y_dataplt.pie(sizes, labels=labels, autopct='%1.1f%%', startangle=140)plt.axis('equal') # 正圆形plt.title(desc[0])plt.show()# 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']
y = [2,3,6]
desc = ['title','x','y']# line = LinePlotStrategy().plot(x, y, desc)
# bar = BarPlotStrategy().plot(x,  y, desc)
# pie = PiePlotStrategy().plot(x,  y, desc)context = Context()context.set_strategy(LinePlotStrategy())
context.execute_strategy(x,  y, desc)context.set_strategy(BarPlotStrategy())
context.execute_strategy(x,  y, desc)context.set_strategy(PiePlotStrategy())
context.execute_strategy(x,  y, desc)

折线图
柱状图
饼图


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 piclass PlotStrategy(ABC):# 抽象类:强制子类实现此方法@abstractmethoddef plot(self, x_data, y_data, desc):passclass LinePlotStrategy(PlotStrategy):def plot(self, x_data, y_data, desc):print('折线图')plt.clf()  # 清除当前图形内容plt.plot(x_data,y_data,color='blue', linestyle='-', linewidth=2, marker='o', markersize=6, label='sin(x)')plt.title(desc[0], fontsize=16)plt.xlabel(desc[1], fontsize=14)plt.ylabel(desc[2], fontsize=14)plt.xticks(fontsize=12)plt.yticks(fontsize=12)plt.legend(fontsize=12)  # 添加图例plt.grid(True)  # 添加网格plt.tight_layout()  # 自动调整布局# plt.show()plt.savefig('./line.png')class BarPlotStrategy(PlotStrategy):def plot(self, x_data, y_data, desc):plt.clf()  # 清除当前图形内容print('柱状图')bars = plt.bar(x_data, y_data,color='skyblue', edgecolor='grey')plt.title(desc[0], fontsize=16)plt.xlabel(desc[1], fontsize=14)plt.ylabel(desc[2], fontsize=14)# 添加数值标签for bar in bars:plt.text(bar.get_x() + bar.get_width() / 2, bar.get_height(),round(bar.get_height(), 1), ha='center', va='bottom')plt.xticks(fontsize=12)plt.yticks(fontsize=12)plt.tight_layout()  # 自动调整布局# plt.show()plt.savefig('./bar.png')class PiePlotStrategy(PlotStrategy):def plot(self, x_data, y_data, desc):plt.clf()# 清除当前图形内容print('饼图')labels = x_datasizes = y_dataplt.pie(sizes, labels=labels, autopct='%1.1f%%', startangle=140)plt.axis('equal') # 正圆形plt.title(desc[0])# plt.show()plt.savefig('./pie.png')class SeabornPlotStrategy(PlotStrategy):def plot(self, x_data, y_data, desc):plt.clf()  # 清除当前图形内容print('Seaborn数据可视化库生成折线图')# Seaborn 是基于 matplotlib 的数据可视化库,提供了更高层次的接口,使得统计数据可视化更加简单和美观sns.lineplot(x = x_data,y = y_data)# plt.show()plt.savefig('./line_seaborn.png')plt.clf()  # 清除当前图形内容print('Seaborn数据可视化库生成柱状图')# 示例数据data = {'Category': x_data,'Values': y_data}# 创建一个 DataFramedf = pd.DataFrame(data)sns.barplot(x='Category', y='Values', data=df)# plt.show()plt.savefig('./bar_seaborn.png')class PlotlyPlotStrategy(PlotStrategy):def plot(self, x_data, y_data, desc):print('使用 Plotly 画折线图')# 使用 Plotly 画折线图,Plotly 是一个交互式可视化库,支持绘制高质量的动态图表和仪表板。它可以生成 HTML 文件或者在线展示fig = go.Figure(data=go.Scatter(x=x_data, y=y_data))# fig.show()# 需要安装 kaleido 这个附加依赖,它是 Plotly 的推荐渲染引擎# pio.write_image(fig, './line_plotly.png') # 执行失败,执行到此步骤 长时间无响应# fig.write_image('./line_plotly.png')      # 执行失败,执行到此步骤 长时间无响应fig.write_html('./line_plotly.html')print('使用 Plotly 画柱状图')fig = go.Figure(data=go.Bar(x=x_data, y=y_data))fig.update_layout(title=desc[0],xaxis=dict(title=desc[1]),yaxis=dict(title=desc[2]))# fig.show()fig.write_html('./bar_plotly.html')print('使用 Plotly 画饼图')fig = go.Figure(data=go.Pie(labels=x_data, values=y_data))fig.update_layout(title=desc[0])# fig.show()fig.write_html('./pie_plotly.html')class AltairPlotStrategy(PlotStrategy):def plot(self, x_data, y_data, desc):# Altair 是一个 Python 可视化库,使用简洁的声明式语法创建交互式可视化print('使用 Altair 画折线图')# 创建示例数据data = pd.DataFrame({'x': x_data,'y': y_data})# 创建折线图line_chart = alt.Chart(data).mark_line().encode(x='x',y='y').properties(title=desc[0])# 显示折线图line_chart.save('./line_altair.html')print('使用 Altair 画柱状图')# 创建示例数据data = pd.DataFrame({'x': x_data,'y': y_data})# 创建柱状图bar_chart = alt.Chart(data).mark_bar().encode(x='x',y='y').properties(title=desc[0])# 显示柱状图bar_chart.save('./bar_altair.html')print('使用 Altair 画饼图')# 创建示例数据data = pd.DataFrame({'category': x_data,'value': y_data})# 计算百分比data['percent'] = (data['value'] / (data['value'].sum()) * 100).round(2)# 创建饼图pie_chart = alt.Chart(data).mark_arc(size=200,  # 设置饼图的大小outerRadius=150  # 设置饼图半径).encode(theta='value:Q',  # 角度根据value列的值来编码color='category:N',  # 颜色根据category列的值来编码tooltip=['category', 'percent:Q'],  # tooltip显示category和percent列).properties(width=300,height=300,title=desc[0])# 显示饼图,Altair 不直接支持在每个扇区上显示两个不同的文本标签(值和百分比)pie_chart.save('./pie_altair.html')class BokehPlotStrategy(PlotStrategy):def plot(self, x_data, y_data, desc):# 使用 Bokeh 画折线图,Plotly 是一个交互式的可视化库,可以生成漂亮的图表,并支持与用户交互,例如缩放、悬停等操作# 官方文档:https://docs.bokeh.org/en/latest/docs/user_guide/basic/lines.htmlprint('使用 Bokeh 画折线图')# # 创建绘图对象# output_file("./line_bokeh.html")# p = figure(width=400, height=400)## # add a line renderer# p.line(x_data, y_data, line_width=2)# # 显示图表# show(p)print('使用 Bokeh 画柱状图')p = figure(x_range=x_data, height=350, title=desc[0],toolbar_location=None, tools="")p.vbar(x=x_data, top=y_data, width=0.9)p.xgrid.grid_line_color = Nonep.y_range.start = 0output_file("./bar_bokeh.html")show(p)print('使用 Bokeh 画饼图')categories = x_data  # 图例标签values = y_data  # 饼图的数值# 计算起始和结束角度start_angles = [2 * pi * i / sum(values) for i, _ in enumerate(values[:-1])]end_angles = [2 * pi * (i + 1) / sum(values) for i, _ in enumerate(values)]# 创建绘图对象p = figure(title=desc[0], x_axis_type=None, y_axis_type=None, toolbar_location=None)# 绘制饼图,确保legend_label是字符串for i, (start, end, cat) in enumerate(zip(start_angles, end_angles, categories)):p.wedge(x=0, y=1, radius=0.8,start_angle=start, end_angle=end,line_color="white", fill_color="blue",  # 可以为每个扇形设置不同的颜色legend_label=str(cat))  # 确保legend_label是字符串# 添加图例p.legend.location = "top_right"p.legend.click_policy = "hide"  # 可选:点击图例项来隐藏/显示对应的图形# 显示图表output_file("pie_bokeh.html")show(p)# 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','F','G']
y = [2,3,6,1,4,4,3]
x1 = [1,2,3,4,5,6,7]
desc = ['title','x','y']# line = LinePlotStrategy().plot(x, y, desc)
# bar = BarPlotStrategy().plot(x,  y, desc)
# pie = PiePlotStrategy().plot(x,  y, desc)
# seab = SeabornPlotStrategy().plot(x,y,desc)context = Context()context.set_strategy(LinePlotStrategy())
context.execute_strategy(x,  y, desc)context.set_strategy(BarPlotStrategy())
context.execute_strategy(x,  y, desc)context.set_strategy(PiePlotStrategy())
context.execute_strategy(x,  y, desc)context.set_strategy(SeabornPlotStrategy())
context.execute_strategy(x,  y, desc)context.set_strategy(PlotlyPlotStrategy())
context.execute_strategy(x,  y, desc)context.set_strategy(AltairPlotStrategy())
context.execute_strategy(x,  y, desc)context.set_strategy(BokehPlotStrategy())
context.execute_strategy(x,  y, desc)

折线图
柱状图
饼图
Seaborn数据可视化库生成折线图
Seaborn数据可视化库生成柱状图
使用 Plotly 画折线图
使用 Plotly 画柱状图
使用 Plotly 画饼图
使用 Altair 画折线图
使用 Altair 画柱状图
使用 Altair 画饼图
使用 Bokeh 画折线图
使用 Bokeh 画柱状图
使用 Bokeh 画饼图

网格和布局 — Bokeh 3.4.1 文档

 

Specifying Data — Vega-Altair 5.3.0 documentation (altair-viz.github.io)

 

Plotly Python 图形库

Python API 参考 plotly — 5.22.0 文档

 Seaborn:统计数据可视化 — Seaborn 0.13.2 文档 (pydata.org)

API reference — seaborn 0.13.2 documentation

User guide and tutorial — seaborn 0.13.2 documentation

相关文章:

  • GenICam标准(二)
  • 科普文章:怎么远程监控电脑屏幕?三种监控电脑屏幕的方法
  • 基于mysqlbinlog恢复数据
  • 让我们拯救数学
  • 探索Linux命令的新利器:linux-command
  • 【ARMv8/v9 GIC 系列 2 -- GIC SPI 中断的 enable和 disable 配置】
  • SpringSecurity实战入门——认证
  • React+TS前台项目实战(九)-- 全局常用组件弹窗Dialog封装
  • Mybatis Plus 详解 IService、BaseMapper、自动填充、分页查询功能
  • Python基础教程(二十四):日期和时间
  • 第六章 图论与网络分析 (重点,熟练掌握三算法) 树图和图的最小部分树 最短路问题 网络的最大流
  • 24年计算机等级考试22个常见问题解答❗
  • 23种设计模式之桥接模式
  • 【Unity设计模式】状态编程模式
  • Git与SSH
  • ----------
  • [PHP内核探索]PHP中的哈希表
  • 【Leetcode】101. 对称二叉树
  • Android开发 - 掌握ConstraintLayout(四)创建基本约束
  • gops —— Go 程序诊断分析工具
  • LeetCode541. Reverse String II -- 按步长反转字符串
  • log4j2输出到kafka
  • springboot_database项目介绍
  • 对超线程几个不同角度的解释
  • 面试总结JavaScript篇
  • 一天一个设计模式之JS实现——适配器模式
  • 一些css基础学习笔记
  • 正则学习笔记
  • nb
  • ​2021半年盘点,不想你错过的重磅新书
  • ‌内网穿透技术‌总结
  • #includecmath
  • #我与Java虚拟机的故事#连载05:Java虚拟机的修炼之道
  • (23)Linux的软硬连接
  • (C语言)二分查找 超详细
  • (LeetCode C++)盛最多水的容器
  • (附源码)ssm捐赠救助系统 毕业设计 060945
  • (附源码)计算机毕业设计SSM智能化管理的仓库管理
  • (十三)Flink SQL
  • (五十)第 7 章 图(有向图的十字链表存储)
  • (原创)boost.property_tree解析xml的帮助类以及中文解析问题的解决
  • (转)C语言家族扩展收藏 (转)C语言家族扩展
  • (转)大道至简,职场上做人做事做管理
  • (最简单,详细,直接上手)uniapp/vue中英文多语言切换
  • .desktop 桌面快捷_Linux桌面环境那么多,这几款优秀的任你选
  • .net core MVC 通过 Filters 过滤器拦截请求及响应内容
  • .net core 实现redis分片_基于 Redis 的分布式任务调度框架 earth-frost
  • .NET 常见的偏门问题
  • .NET微信公众号开发-2.0创建自定义菜单
  • //TODO 注释的作用
  • [ vulhub漏洞复现篇 ] Django SQL注入漏洞复现 CVE-2021-35042
  • [001-03-007].第07节:Redis中的管道
  • [2016.7 test.5] T1
  • [7] CUDA之常量内存与纹理内存
  • [AIGC] Java 和 Kotlin 的区别