import sys, numpy as np, os, re from matplotlib import pyplot as plt, rc, rcParams, ticker import crl from matplotlib.patches import Polygon from matplotlib.collections import PatchCollection class Bounds: def __init__(self): self.xmin = 0 self.xmax = 0 self.ymin = 0 self.ymax = 0 def point(self, x, y): self.xmin = min(self.xmin, x) self.xmax = max(self.xmax, x) self.ymin = min(self.ymin, y) self.ymax = max(self.ymax, y) def extents(self, margin=0): dx = (self.xmax - self.xmin) * margin dy = (self.ymax - self.ymin) * margin return [self.xmin - dx , self.xmax + dx, self.ymin - dy, self.ymax + dy] def set(self, margin=0, ax=plt): xmin, xmax, ymin, ymax = self.extents(margin) plt.xlim(xmin, xmax) plt.ylim(ymin, ymax) def plot_setup(width=1, color_plot=False): rcParams["font.family"] = 'serif' rcParams["font.serif"] = ["C059"] rcParams["font.size"] = 15 rc("text", usetex=True) rc("text.latex", preamble=\ """\\usepackage{polski}""") rcParams["savefig.dpi"] = 200 rcParams["savefig.bbox"] = "tight" figwidth = width * 10 if color_plot: figwidth *= 1.7 figheight = figwidth * 0.75 rcParams['figure.figsize'] = figwidth, figheight def texformatter_func(x, pos): return ("%g" % x).replace(".", "{,}") texformatter = ticker.FuncFormatter(texformatter_func) def plot_grid(ax=plt, minor=True): if minor: ax.minorticks_on() ax.grid(b=True, which='major', linestyle='-', linewidth=0.75, color=[0.8, 0.8, 0.8]) ax.grid(b=True, which='minor', linestyle='--', linewidth=0.75, color=[0.9, 0.9, 0.9]) if ax is plt: ax = plt.gca() ax.xaxis.set_major_formatter(texformatter) ax.yaxis.set_major_formatter(texformatter) #ax.xaxis.set_minor_formatter(texformatter) #ax.yaxis.set_minor_formatter(texformatter) def plot_longline(x1, y1, x2, y2, fmt, **kwargs): axes = plt.axis() plt.plot((x1, x2), (y1, y2), fmt, **kwargs) plt.xlim([axes[0], axes[1]]) plt.ylim([axes[2], axes[3]]) def plot_sRGB(CS, D65=True): V = [ crl.sRGB(1, 0, 0), crl.sRGB(0, 1, 0), crl.sRGB(0, 0, 1) ] V.append(V[0]) V = np.array([[*v.to(CS)] for v in V]) plt.plot(V[:, 0], V[:, 1], "k:", label="sRGB") if D65: x, y, _ = CS(crl.Illuminants.D65) plt.plot(x, y, "k^", label="$\\mathrm{D}_{65}$") plt.legend() def plot_export(): if len(sys.argv) > 1: plt.savefig(sys.argv[1]) else: plt.show() def plot_colorbar(X, C): C = np.expand_dims(C, axis=0) ar = 10 plt.imshow(C, extent=[min(X), max(X), min(X) / ar, max(X) / ar]) plt.gca().axes.get_yaxis().set_visible(False) def plot_Ra(res, extended=True): crl.chromaticity_diagram(crl.UVstarNormedD65, locus=False) bounds = Bounds() for i in range(14 if extended else 8): u, v, _ = crl.UVstarNormed.from_UVWstar(res.tcs[i]) u0, v0, _ = crl.UVstarNormed.from_UVWstar(res.tcs_ref[i]) if np.sqrt((u - u0)**2 + (v - v0)**2) > 0.07: plt.arrow(u0, v0, u - u0, v - v0, width=0.004, length_includes_head=True, ec=None, fc="k") plt.plot(u, v, "ko", markersize=5, label="TCS" if not i else None) plt.scatter(u0, v0, s=50, facecolors="none", edgecolors="k") bounds.point(u, v) bounds.point(u0, v0) plt.plot(0, 0, "kx", label="Punkt bieli") bounds.point(0, 0) bounds.set(margin=0.1) def plot_GAI(points, color="k", pattern="o-", label="Gama", alpha=0.3): poly = Polygon(points) col = PatchCollection([poly], fc=color, ec=color, alpha=alpha) plt.gca().add_collection(col) points = np.concatenate([points, np.array([points[0, :]])], axis=0) plt.plot(points[:, 0], points[:, 1], pattern, color=color, markersize=3, label=label) def prefix(path): return os.path.join(os.path.dirname(__file__), "../lab/", path) class Lamp: def load_ref(path): data = dict() with open(path) as fd: for line in fd: k, v = line.split("\t") v = v.replace(",", ".") match = re.match("CRI R(.*)", k) if match: v = v.split(" ")[0] if match.group(1) == "a": data["CRI"] = float(v) else: if "SCRI" not in data: data["SCRI"] = [0] * 15 data["SCRI"][int(match.group(1)) - 1] = float(v) elif k == "CCT": data["CCT"] = float(v[:-2]) elif k in ["x", "y", "z", "X", "Y", "Z"]: data[k] = float(v) else: data[k] = v data["XYZ"] = crl.XYZ(data["X"], data["Y"], data["Z"]) data["xyY"] = crl.xyY(data["x"], data["y"], data["Y"]) return data def __init__(self, lid, Ra_spec, CCT_spec, path): self.lid = lid self.Ra_spec = Ra_spec self.CCT_spec = CCT_spec data = crl.data.load(prefix(path + "/Surowe.txt")) self.raw = crl.Spectrum(data[:, 0], data[:, 1]) data = crl.data.load(prefix(path + "/Z korekcją.txt")) self.spec = crl.Spectrum(data[:, 0], data[:, 1]) self.ref_2deg = Lamp.load_ref(prefix(path + "/Kolor 2deg.txt")) self.ref_10deg = Lamp.load_ref(prefix(path + "/Kolor 10deg.txt")) self.CCT, self.dE = crl.cct(self.spec) self.Ra = crl.cri_Ra(self.spec) self.GAI, _ = crl.cri_GAI(self.spec) self.FSCI = crl.cri_FSCI(self.spec) def load_labdb(key): return Lamp(key, *labdb[key]) labdb = { "Ż": ["100", 2700, "2 grudnia/E27/Żarówka"], "JA27": ["\geq 80", 2700, "2 grudnia/E27/Jarzeniówka 2700"], "JA65": ["\geq 80", 6500, "2 grudnia/E27/Jarzeniówka 6500"], "JB27": ["\geq 80", 2700, "2 grudnia/E27/Duża jarzeniówka 2700"], "LA": ["\geq 80", 3000, "2 grudnia/E27/LED OSSO"], "LB30": ["80", 3000, "2 grudnia/GU10/LED 3000"], "LB40": ["80", 4000, "2 grudnia/GU10/LED 4000"], "LB65": ["80", 6500, "2 grudnia/GU10/LED 6500"], "LB97": ["97", 4000, "6 grudnia/OSRAM"], "LC1": ["\geq 72", 4000, "2 grudnia/GU10/Chiński I"], "LC2": ["\geq 72", 4000, "2 grudnia/GU10/Chiński II"], "LC3": ["\geq 72", 4000, "2 grudnia/GU10/Chiński III"], "LC4": ["\geq 72", 4000, "2 grudnia/GU10/Chiński IV"], "LC5": ["\geq 72", 4000, "2 grudnia/GU10/Chiński V"], "T28": ["95", 2800, "6 grudnia/L2 2800K CRI95"], "T30": ["95", 3000, "6 grudnia/L2 3000K CRI95"], #"T30b": ["95", 3000, "6 grudnia/L2 3000K CRI95 bez soczewki"], "T32": ["95", 3200, "6 grudnia/B2 3200K CRI95"], "T40": ["96", 4000, "6 grudnia/B2 4000K CRI96"] } class TexWriter(): def __init__(self, path): self.path = path def __enter__(self): self.fd = open(self.path, "w") return self def __exit__(self, type, value, traceback): self.fd.close() def write(self, text): self.fd.write(text.replace(".", "{,}"))