-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathdunestyle.py
More file actions
155 lines (124 loc) · 6.21 KB
/
dunestyle.py
File metadata and controls
155 lines (124 loc) · 6.21 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
""" dunestyle.py (matplotlib edition): DUNE plot style tools for use with matplotlib.
This module simply imports the style defined in the C++ header version of the style.
By default it will be enabled immediately on import.
If you do not want it enabled on import, set the global:
```
import builtins # this only works with Python3...
builtins.__dict__["DUNESTYLE_ENABLE_AUTOMATICALLY"] = False
import dunestyle
```
Then you can call dunestyle.enable() to turn it on.
:author: J. Wolcott <jwolcott@fnal.gov>
:date: March 2022
"""
import os
from matplotlib import pyplot as plt
def enable():
import os
path = os.path.join(os.environ['MPLCONFIGDIR'].split(os.pathsep)[0], "dune.mplstyle")
assert os.path.exists(path), "Can't locate DUNE matplotlib style sheet file! I tried path: " + path
plt.style.use(path)
print("DUNE plot style enabled")
import builtins
_IMPORT_FLAG_NAME = "DUNESTYLE_ENABLE_AUTOMATICALLY"
if _IMPORT_FLAG_NAME not in builtins.__dict__ or builtins.__dict__[_IMPORT_FLAG_NAME]:
enable()
########## Utility functions below ################
def _GetTransform(transform=None, ax=None):
""" Used in the text functions below. Not intended for end-users """
if transform is not None:
return transform
if ax is not None and hasattr(ax, "transAxes"):
return ax.transAxes
return plt.gca().transAxes
def TextLabel(text, x, y, transform=None, ax=None, **kwargs):
"""
Add a text label at an arbitray place on the plot.
Mostly used as an internal utility for the more specific label functions,
but end-users can feel free to use as well.
:param text: Text to write
:param x: Intended x-coordinate
:param y: Intended y-coordinate
:param transform: If you want to use a transformation other than the default transAxes, supply here.
:param ax: If you prefer to pass an Axes directly (perhaps you have multiple in a split canvas), do so here
:param kwargs: Any other arguments will be passed to pyplot.text()
:return: None
"""
plotter = plt if ax is None else ax
kwargs.setdefault("fontdict", {})
kwargs["fontdict"]["fontsize"] = 18
if "color" in kwargs:
kwargs["fontdict"]["color"] = kwargs.pop("color")
if "fontsize" in kwargs:
kwargs["fontdict"]["fontsize"] = kwargs.pop("fontsize")
if "align" in kwargs:
kwargs["horizontalalignment"] = kwargs.pop("align")
plotter.text(x, y, text,
transform=_GetTransform(transform, plotter),
**kwargs)
def DUNEWatermarkString():
"""
Produces the "DUNE" part of the string used in watermarks so it can be styled independently if necessary
:return: The appropriately styled "DUNE" string
"""
return r"$\mathdefault{\bf{DUNE}}$"
def Preliminary(x=0.05, y=0.90, align='left', transform=None, ax=None, **kwargs):
"""
Apply a "DUNE Preliminary" label.
:param x: x-location for the label. Default is just inside the frame on the left.
:param y: y-location for the label. Default is just inside the frame on the top.
:param align: Text alignment (note: not placement!) for the label. Default is left-align.
:param transform: If you want to use a transformation other than the default transAxes, supply here.
:param ax: If you prefer to pass an Axes directly (perhaps you have multiple in a split canvas), do so here
:param kwargs: Any other arguments will be passed to pyplot.text()
:return: None
"""
TextLabel(DUNEWatermarkString() + " Preliminary", x, y, ax=ax, transform=transform, align=align, color="black", **kwargs)
def WIP(x=0.05, y=0.90, align='left', transform=None, ax=None, **kwargs):
"""
Apply a "DUNE Work In Progress" label.
See help on TextLabel() for the optional parameters.
"""
TextLabel(DUNEWatermarkString() + " Work In Progress", x, y, ax=ax, transform=transform, align=align, color="black", **kwargs)
def Simulation(x=0.05, y=0.90, align='left', ax=None, transform=None, **kwargs):
"""
Apply a "DUNE Simulation" label.
See help on TextLabel() for the optional parameters.
"""
TextLabel(DUNEWatermarkString() + " Simulation", x, y, ax=ax, transform=transform, align=align, color="black", **kwargs)
def SimulationSide(x=1.05, y=0.5, align='right', ax=None, transform=None, **kwargs):
"""
Apply a "DUNE Simulation" label on the right outside of the frame.
NOTE: the Simulation() version is heavily preferred over this one;
this "outside-the-canvas" version exists for special cases when
there are already too many other labels inside it.
See on TextLabel() for the optional parameters.
"""
TextLabel(DUNEWatermarkString() + " Simulation", x, y, ax=ax, transform=transform, align=align, rotation=270, color="black", **kwargs)
def Official(x=0.05, y=0.90, align='left', ax=None, transform=None, **kwargs):
"""
Apply a "DUNE" label (for officially approved results only).
See help on TextLable() for the optional parameters.
"""
TextLabel(DUNEWatermarkString(), x, y, ax=ax, transform=transform, align=align, color="black", **kwargs)
def CornerLabel(label, ax=None, transform=None, **kwargs):
"""
Apply a gray label with user-specified text on the upper-left corner (outside the plot frame).
See help on TextLabel() for the optional parameters.
"""
TextLabel(label, 0, 1.05, ax=ax, transform=transform, color="gray", **kwargs)
def SetDUNELogoColors():
""" Set the color cycler to use the subset of Okabe-Ito colors that overlap with the DUNE logo colors. """
from cycler import cycler
cyc = cycler(color=['#D55E00', '#56B4E9', '#E69F00'])
plt.rc("axes", prop_cycle=cyc)
def SetOkabeItoColors():
""" Set the color cycler to use Okabe-Ito colors.. """
from cycler import cycler
cyc = cycler(color=['#000000', '#D55E00', '#56B4E9', '#E69F00', '#009E73', '#CC79A7', '#0072B2', '#F0E442',])
plt.rc("axes", prop_cycle=cyc)
def off_white_bkg():
""" Set the background color of the figure to match the off-white background of the updated DUNE slide template. """
plt.rcParams['axes.facecolor'] = '#f0f0f0'
plt.rcParams['figure.facecolor'] = '#f0f0f0'
plt.rcParams['savefig.facecolor'] = '#f0f0f0'