Created
August 7, 2019 18:23
-
-
Save redraiment/1c6eee9be47434aeeeecbc91979e5c2a to your computer and use it in GitHub Desktop.
基于Matplotlib的图表库简单封装,方便绘制直方图、圆饼图、折线图、散点图和箱形图。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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