Skip to content

Instantly share code, notes, and snippets.

@redraiment
Created August 7, 2019 18:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save redraiment/1c6eee9be47434aeeeecbc91979e5c2a to your computer and use it in GitHub Desktop.
Save redraiment/1c6eee9be47434aeeeecbc91979e5c2a to your computer and use it in GitHub Desktop.
基于Matplotlib的图表库简单封装,方便绘制直方图、圆饼图、折线图、散点图和箱形图。
#!/usr/bin/env python3
# -- 非线程安全 --
from matplotlib.font_manager import FontProperties
from operator import itemgetter
from itertools import groupby
import matplotlib.pyplot as canvas
import numpy as np
# constants
DPI=100
CHINESE = FontProperties(fname = '/System/Library/Fonts/PingFang.ttc', size = 12)
# private utilities
def _get(values, index, default = None):
return values[index] if 0 <= index < len(values) else default
# privates
def _initialize(width, height, font_size):
global CHINESE, DPI
CHINESE.set_size(font_size)
canvas.clf()
canvas.figure(figsize=(width / float(DPI), height / float(DPI)), dpi=DPI)
def _decorate(title, legend, axis):
global CHINESE
if title:
canvas.title(title, fontproperties=CHINESE)
if legend and 'position' in legend:
canvas.legend(loc=legend['position'], prop=CHINESE)
if axis:
if 'x' in axis:
if 'label' in axis['x']:
canvas.xlabel(axis['x']['label'], fontproperties=CHINESE)
if 'ticks' in axis['x'] and axis['x']['ticks']:
ticks = axis['x']['ticks']
canvas.xticks([tick['value'] for tick in ticks],
[tick.get('label', tick['value']) for tick in ticks],
fontproperties=CHINESE)
if 'y' in axis:
if 'label' in axis['y']:
canvas.ylabel(axis['y']['label'], fontproperties=CHINESE)
if 'ticks' in axis['y'] and axis['y']['ticks']:
ticks = axis['y']['ticks']
canvas.yticks([tick['value'] for tick in ticks],
[tick.get('label', tick['value']) for tick in ticks],
fontproperties=CHINESE)
def _save(to):
global DPI
canvas.savefig(to, dpi=DPI)
def _draw(fn, data, to, title, legend, axis, width, height, font_size):
_initialize(width, height, font_size)
if type(data) is list:
for element in data:
fn(element)
else:
fn(data)
_decorate(title, legend, axis)
_save(to)
# draw
def _bar(data):
labels = data.get('labels', [data.get('label', '')])
values = data['values']
size = len(values)
xs = np.linspace(0, size, size, endpoint=False)
ys = [(e['y'] if type(e['y']) is list else [e['y']]) for e in values]
times = max([len(y) for y in ys])
width = data.get('width', 0.8) / float(times)
for index in range(times):
canvas.bar(xs + (0.1 + index * width),
[_get(y, index, 0) for y in ys],
label=_get(labels, index, ''),
width=width,
align='edge')
ticks = [str(e['x']) for e in values]
canvas.xticks(xs + 0.5, ticks, fontproperties=CHINESE)
def _box(data):
global CHINESE
get_x = itemgetter('x')
values = groupby(sorted(data['values'], key=get_x), get_x)
points = [(k, [v['y'] for v in vs]) for k, vs in values]
canvas.boxplot([p[1] for p in points], showmeans=True)
canvas.xticks(np.linspace(1, len(points), len(points)),
[p[0] for p in points],
fontproperties=CHINESE)
def _plot(data):
canvas.plot([e['x'] for e in data['values']],
[e['y'] for e in data['values']],
label=data.get('label', ''),
linestyle=data.get('style', '-'),
linewidth=data.get('width', None),
color=data.get('color', None))
def _scatter(data):
canvas.scatter([e['x'] for e in data['values']],
[e['y'] for e in data['values']],
label=data.get('label', ''))
def _pie(data):
global CHINESE
values = sorted(data['values'], key=itemgetter('y'), reverse=True)
canvas.pie([e['y'] for e in values],
labels=[e['x'] for e in values],
autopct='%3.2f%%',
startangle=90,
textprops={'fontproperties':CHINESE})
# exports
def bar(data, to, title=None, legend=None, axis=None, width=1600, height=1200, font_size=12):
_draw(_bar, data, to, title, legend, axis, width, height, font_size)
def box(data, to, title=None, legend=None, axis=None, width=1600, height=1200, font_size=12):
_draw(_box, data, to, title, legend, axis, width, height, font_size)
def plot(data, to, title=None, legend=None, axis=None, width=1600, height=1200, font_size=12):
_draw(_plot, data, to, title, legend, axis, width, height, font_size)
def scatter(data, to, title=None, legend=None, axis=None, width=1600, height=1200, font_size=12):
_draw(_scatter, data, to, title, legend, axis, width, height, font_size)
def pie(data, to, title=None, legend=None, axis=None, width=1600, height=1200, font_size=12):
_draw(_pie, data, to, title, legend, axis, width, height, font_size)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment