Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- # coding: utf-8
- import os, cairo
- from random import choice, random as rnd
- from math import radians
- # = DATA =======================================================================
- def generate_data(print_generated_data):
- set_of_As = ['Столбец №%i' % i for i in range(1,11)]
- set_of_Bs = ['Строка №%i' % i for i in range(1,11)]
- data = {}
- for A in set_of_As:
- for B in set_of_Bs:
- C = rnd() - 0.5
- if C > 0.33-0.5:
- data[A] = data.get(A) or {}
- data[A][B] = C
- if print_generated_data:
- print('%s : %s = %+f' % (A.ljust(12), B.ljust(12), C))
- return set_of_As, set_of_Bs, data
- def data_from_file(filename):
- ## A : B = C
- data = {}
- As, Bs = set(), set()
- for line in open(filename):
- AB, Cstr = line.split('=', 1)
- A, B = map(str.strip, AB.split(':', 1))
- C = float(Cstr)
- data[A] = data.get(A) or {}
- data[A][B] = C
- As |= {A}
- Bs |= {B}
- return sorted(As), sorted(Bs), data
- #~ set_of_As, set_of_Bs, DATA = data_from_file('data.txt')
- set_of_As, set_of_Bs, DATA = generate_data(False)
- # = SETUP ======================================================================
- COL_WIDTH = 60
- ROW_HEIGHT = 25
- BORDER = 10
- FIRST_COL_OFFSET = BORDER + 130 # text baseline of the first column header
- FIRST_ROW_OFFSET = BORDER + 120 # text baseline of the first row
- COL_NAMES_ROTATION = 75
- CELL_FORMAT = '%+.3f'
- CELL_PADDING_LEFT = 10
- FONT = 'Open Sans Light'
- #~ FONT = 'Sans'
- FONT_SIZE = 14
- GRID_ALPHA = 0.05 # color is semirandom :)
- FILE_NAME = 'image.png'
- #~ FILE_NAME = 'image.svg'
- # = DRAWING CONTEXT SETUP ======================================================
- WIDTH = FIRST_COL_OFFSET + len(set_of_As) * COL_WIDTH + BORDER - COL_WIDTH//2
- HEIGHT = FIRST_ROW_OFFSET + (len(set_of_Bs)-1) * ROW_HEIGHT + BORDER + \
- (ROW_HEIGHT - FONT_SIZE)//2 + 2
- class MyCairoContext(cairo.Context):
- def text(c, text, x, y, a=0):
- c.save()
- c.translate(x, y)
- c.rotate(radians(-a))
- c.translate(-x, -y)
- c.move_to(x, y)
- c.show_text(text)
- c.restore()
- c.new_path()
- if FILE_NAME.lower().endswith('.svg'):
- SURF = cairo.SVGSurface(FILE_NAME, WIDTH, HEIGHT)
- else:
- SURF = cairo.ImageSurface(cairo.FORMAT_ARGB32, WIDTH, HEIGHT)
- c = MyCairoContext(SURF)
- c.set_source_rgb(1, 1, 1)
- c.paint()
- c.select_font_face(FONT, cairo.FONT_SLANT_NORMAL, cairo.FONT_WEIGHT_NORMAL)
- c.set_font_size(FONT_SIZE)
- # = DRAWING ====================================================================
- # Column names and grid
- y = FIRST_ROW_OFFSET - ROW_HEIGHT//2 - FONT_SIZE
- for i, A in enumerate(set_of_As):
- if not i%2: # vertical grid
- c.set_source_rgba(0, 0, rnd(), GRID_ALPHA) # grid color
- x = i * COL_WIDTH + FIRST_COL_OFFSET - COL_WIDTH/2
- c.rectangle(x, BORDER, COL_WIDTH, HEIGHT-BORDER*2)
- c.fill()
- c.set_source_rgb(0, rnd(), rnd()) # text color
- x = i * COL_WIDTH + FIRST_COL_OFFSET
- c.text(A, x, y, COL_NAMES_ROTATION)
- # Row names and grid
- x = BORDER + 10
- for i, B in enumerate(set_of_Bs):
- if not i%2: # horizontal grid
- c.set_source_rgba(rnd(), 0, 0, GRID_ALPHA) # grid color
- y = i * ROW_HEIGHT + FIRST_ROW_OFFSET - ROW_HEIGHT/2 - FONT_SIZE/2 + 2
- c.rectangle(BORDER, y, WIDTH-BORDER*2, ROW_HEIGHT)
- c.fill()
- c.set_source_rgb(rnd(), rnd(), 0) # text color
- y = i * ROW_HEIGHT + FIRST_ROW_OFFSET
- c.text(B, x, y)
- # Cell data
- c.set_source_rgb(0.1, 0.1, 0.1) # text color, dark grey, almost black
- for A in DATA:
- for B in DATA[A]:
- C = DATA[A][B]
- x = set_of_As.index(A) * COL_WIDTH + FIRST_COL_OFFSET - COL_WIDTH/2
- y = set_of_Bs.index(B) * ROW_HEIGHT + FIRST_ROW_OFFSET
- c.text(CELL_FORMAT % C, x + CELL_PADDING_LEFT, y)
- # = OUTPUT IF RASTER ===========================================================
- if type(SURF) is cairo.ImageSurface:
- SURF.write_to_png(FILE_NAME)
- os.system('feh -F %s' % FILE_NAME) # 'feh' is an image viewer
Add Comment
Please, Sign In to add comment