Python数据可视化
基于asciichartpy
import asciichartpy data = [1, 2, 3, 4, 5, 4, 3, 2, 1] chart = asciichartpy.plot(data) print(chart)

基于sparklines
import sparklines data = [1, 2, 3, 4, 5, 4, 3, 2, 1] sparkline_str = ''.join(sparklines.sparklines(data)) print(sparkline_str)

基于sparkline-nb将曲线插入dataframe
import io
import base64
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from IPython.display import display, HTML
def sparkline(data, figsize=(4, 0.25), **kwargs):
"""
Returns an HTML image tag containing a base64 encoded sparkline style plot
"""
data = list(data)
fig, ax = plt.subplots(1, 1, figsize=figsize, **kwargs)
ax.plot(data)
for k, v in ax.spines.items():
v.set_visible(False)
ax.set_xticks([])
ax.set_yticks([])
plt.plot(len(data) - 1, data[len(data) - 1], 'r.')
ax.fill_between(range(len(data)), data, [min(data)]*len(data), alpha=0.1)
img = io.BytesIO()
plt.savefig(img, format='png')
img.seek(0)
plt.close()
# Encode the image in base64
img_base64 = base64.b64encode(img.read()).decode('utf-8')
return f'<img src="data:image/png;base64,{img_base64}"/>'
if __name__ == "__main__":
n = 4
data = [
('rand', np.random.rand(n)),
('randn', np.random.randn(n)),
('beta', np.random.beta(2, 1, size=n)),
('binomial', np.random.binomial(3.4, 0.22, size=n)),
('exponential', np.random.exponential(size=n)),
('geometric', np.random.geometric(0.5, size=n)),
('laplace', np.random.laplace(size=n))
]
spark = pd.DataFrame(data, columns=['func', 'data'])
print(spark)
# map the sparkline function over the data column
# and store back in the column sparklines
spark['sparklines'] = spark.data.map(sparkline)
# _repr_html_ escapes HTML so manually handle the rendering
HTML(spark.to_html(escape=False))

基于xlsxwriter在Excel里插入曲线
import xlsxwriter
wb = xlsxwriter.Workbook('hello.xlsx')
ws = wb.add_worksheet()
data=[12,23,9,17,31,3,7,21,10,15]
ws.write_row('A1', data)
ws.set_column('K:K', 40)
ws.set_row(0, 30)
data=[1,1,-1,-1,-1,1,1,1,-1,-1]
ws.write_row('A5', data)
ws.set_column('K:K', 40)
ws.set_row(4, 30)
ws.add_sparkline('K1', {'range':'Sheet1!A1:J1', 'markers':True})
ws.add_sparkline('K5', {'range':'Sheet1!A5:J5', 'type':'win_loss',
'negative_points':True})
wb.close()
# 更多参数
ws.add_sparkline(idx + 1, offset - 1, {
'range': data_sheet_loc,
'markers': False,
'markers_color': 'purple',
'series_color': 'blue',
'high_point': 'red',
'high_color': 'red',
'low_point': 'green',
'low_color': 'green'
}
)

基于matplotlib.pyplot先生成png,然后再插入Excel的方法
import os
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib.ticker as mticker
from matplotlib import font_manager
from openpyxl import load_workbook
from openpyxl.drawing.image import Image
def insert_pic(excel_path, pic_path, height):
if not os.path.exists(excel_path):
log.error("failed to insert pic because of missing {}".format(excel_path))
return
if not os.path.exists(pic_path):
log.error("failed to insert pic because of missing {}".format(pic_path))
return
print(excel_path, pic_path)
xl = load_workbook(excel_path)
xl_sheet = xl[xl.sheetnames[0]]
pos = "B" + str(xl_sheet.max_row + height + 5)
img = Image(pic_path)
xl_sheet.add_image(img, pos)
xl.save(excel_path)
xl.close()
matplotlib.pyplot画图示例
# X 轴数据
dis = pd.date_range(start='2025-01-17 09:20:00', end='2025-01-20 09:20:00', freq="5min", closed="left")
# 创建figure绘图
plt.figure(figsize=(15, 6))
plt.title("Test Title")
plt.plot(dis, vals, label='PV')
plt.axvline(x=xxx, color='r', linestyle='--', linewidth=0.7, label='调整时间点')
# 去掉左右的空隙,设置X轴范围
plt.xlim(dis.min(), dis.max())
# 定义日期格式化器, 获取当前 Axes 对象, 设置 X 轴刻度标签的格式
date_format = DateFormatter('%Y-%m-%d %H:%M:%S')
ax = plt.gca()
ax.xaxis.set_major_formatter(date_format)
# 设置 X 轴刻度,使第一个和最后一个坐标也被标识出来
num_ticks = 12
xticks = pd.date_range(start=dis.min(), end=dis.max(), periods=num_ticks)
plt.xticks(xticks, rotation=45)
plt.xlabel('时间')
plt.ylabel('人数')
plt.legend()
plt.grid()
plt.show()
补充示例:
import os
import json
import time
import datetime
import traceback
import pandas as pd
import matplotlib.ticker as mticker
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
from matplotlib import font_manager
fname="/usr/local/python3.6/lib/python3.6/site-packages/matplotlib/mpl-data/fonts/ttf/simhei.ttf"
zhfont = font_manager.FontProperties(fname=fname)
dis = pd.date_range(start=stime, end=etime, freq="5min", closed="left")
total_tss = [ int(di.tz_localize("Asia/Shanghai").timestamp()) for di in dis.to_list() ]
plt.figure(figsize=(15, 6))
plt.title("任务执行耗时变化情况")
# plt.plot(dis, spent_lst, label='耗时(秒)')
plt.scatter(dis, spent_lst, alpha=0.5, s=10) # 数据较多时候使用散点图
# 去掉左右的空隙,设置X轴范围
plt.xlim(dis.min(), dis.max())
# 定义日期格式化器, 获取当前 Axes 对象, 设置 X 轴刻度标签的格式
date_format = mdates.DateFormatter('%m-%d %H:%M')
ax = plt.gca()
ax.xaxis.set_major_formatter(date_format)
# 设置 X 轴刻度,使第一个和最后一个坐标也被标识出来
num_ticks = 24
xticks = pd.date_range(start=dis.min(), end=dis.max(), periods=num_ticks)
plt.xticks(xticks, rotation=45)
plt.xlabel('时间')
plt.ylabel('任务执行耗时')
plt.legend()
plt.grid()
plt.show()
精细化控制时间显示:
# 确保timestamp是datetime类型(已经是北京时间,无需转换)
df['timestamp'] = pd.to_datetime(df['timestamp'])
# # 如果timestamp没有时区信息,假设它是UTC时间,然后转换为北京时间
# if df['timestamp'].dt.tz is None:
# # 假设数据是UTC时间,转换为北京时间(UTC+8)
# df['timestamp'] = df['timestamp'].dt.tz_localize('UTC').dt.tz_convert('Asia/Shanghai')
# else:
# # 如果已有时区信息,直接转换
# df['timestamp'] = df['timestamp'].dt.tz_convert('Asia/Shanghai')
# ========== 图1: 带宽数据单独一张图 ==========
fig, ax = plt.subplots(figsize=(14, 6))
ax.plot(df['timestamp'], df['bandwidth_mbps'], linewidth=1, color='#2E86AB', marker='o', markersize=1)
ax.set_title('Bandwidth Over Time', fontsize=16, fontweight='bold')
ax.set_xlabel('Time', fontsize=12)
ax.set_ylabel('Bandwidth (Mbps)', fontsize=12)
ax.grid(True, alpha=0.3)
ax.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d %H:%M'))
ax.xaxis.set_major_locator(mdates.HourLocator(interval=6))
ax.tick_params(axis='x', rotation=45)
plt.tight_layout()
plt.show()
支持中文显示问题
######################## 设置全局字体 ########################
import matplotlib
from matplotlib import font_manager
# 1. 先注册字体文件(告诉matplotlib字体文件的位置)
font_path = "/usr/local/python3.6/lib/python3.6/site-packages/matplotlib/mpl-data/fonts/ttf/simhei.ttf"
font_manager.fontManager.addfont(font_path)
# 2. 获取字体名称(从字体文件中读取)
prop = font_manager.FontProperties(fname=font_path)
font_name = prop.get_name() # 获取字体名称,通常是 'SimHei'
# 3. 全局设置中文字体
matplotlib.rcParams['font.sans-serif'] = [font_name]
matplotlib.rcParams['axes.unicode_minus'] = False # 解决负号显示问题
######################## 设置局部字体 ########################
import matplotlib.pyplot as plt
from matplotlib import font_manager
zhfont = font_manager.FontProperties(fname="/usr/local/python3.6/lib/python3.6/site-packages/matplotlib/mpl-data/fonts/ttf/simhei.ttf")
plt.title('中文标题', fontsize=12, fontproperties=zhfont) # 指定中文字体
plt.annotate(
"中文annotate",
xy=(x_95_point, y_95_point),
fontproperties=zhfont # 指定中文字体
)
plt.plot(x_5min, vals, label="中文label")
plt.legend(prop=zhfont) # 指定中文字体
...
作者:Standby — 一生热爱名山大川、草原沙漠,还有我们小郭宝贝!
出处:http://www.cnblogs.com/standby/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
出处:http://www.cnblogs.com/standby/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

浙公网安备 33010602011771号