Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add config option #18

Merged
merged 3 commits into from
Jan 26, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,13 @@ fp.add_page(
nrows=3, ncols=2, orientation="portrait", height_ratios=[1, 1, 2]
)
```
FigPager options read from an .ini file can be updated via the instance's config. The syntax is config[section][subsection][option] = value.
```
fp.config['Text']['Document Title']['text']
```


The FigPager instance can be be closed following the example below.
Finally, FigPager instance can be closed following the example below.
```
fp.close()
```
Expand Down
140 changes: 85 additions & 55 deletions figpager/figpager.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
Written by Eben Pendleton
MIT License
"""

# used to deep copy config
import copy
# used in metadata
Expand All @@ -20,7 +21,9 @@
matplotlib.use('Agg')

# used to draw lines on the figure
import matplotlib.lines as lines
import matplotlib.lines as lines # isort: split
# used to validate and read in ini files
import configobj
# matplotlib import used in setting figure and axes
import matplotlib.pyplot as plt
# import package resources to get ini
Expand All @@ -29,9 +32,6 @@
from matplotlib.backends.backend_pdf import PdfPages
# used to set the plot layout in the figure
from matplotlib.gridspec import GridSpec

# used to validate and read in ini files
import configobj
# import the validator
from validate import Validator

Expand Down Expand Up @@ -64,7 +64,6 @@ def float_list_value(v, minl=None, maxl=None, minv=None, maxv=None):

return [is_float(mem, min=minv, max=maxv) for mem in is_list(v, minl, maxl)]


class FigPager:

""" Class to use matplotlib's figure with multi and single page outputs """
Expand All @@ -74,7 +73,7 @@ class FigPager:
path = os.path.abspath(__file__)

# used to find ini files saved in the package
page_layout_path = pkg_resources.resource_filename('figpager', 'page_layout/')
page_layout_path = pkg_resources.resource_filename("figpager", "page_layout/")

def __init__(
self,
Expand Down Expand Up @@ -167,8 +166,6 @@ def __init__(
# hold outfile full path
self.outfile = outfile



# hold multipage indicator
self.multipage = False
if self.type in ["pdf", "pgf"]:
Expand Down Expand Up @@ -204,8 +201,7 @@ def __init__(

# read in the ini file of paper sizes
config = configobj.ConfigObj(
os.path.join(self.page_layout_path, "paper_sizes.ini"),
configspec=spec,
os.path.join(self.page_layout_path, "paper_sizes.ini"), configspec=spec,
)

# validate against the config above
Expand Down Expand Up @@ -533,6 +529,30 @@ def _parse_option(self, section, subsection, option):
except KeyError:
return None

def _parse_option(self, section, subsection, option):

"""
Parse a given config option given the file's section, subsection and option.
Return None if option is not found
Args:
section: config file section. [example]
subsection: config file subsection. [[example]]
option: config file option. example=True

Returns: option value or None

"""

try:
return self.config[section][subsection][option]
except KeyError:
try:
return self.config[section][subsection][self.paper_size.title()][
self.orientation.title()
][option]
except KeyError:
return None

def _update_from_layout(self):

"""
Expand Down Expand Up @@ -574,34 +594,7 @@ def _update_from_layout(self):

self.marginframe = self._parse_option("Layout", "Margin", "margin_frame")
if self.marginframe:
self.constrained_layout = False
self.leftmargin = (
self._parse_option("Layout", "Margin", "left_margin")
* self.figure_unit_conversion
)
self.rightmargin = (
self._parse_option("Layout", "Margin", "right_margin")
* self.figure_unit_conversion
)
self.topmargin = (
self._parse_option("Layout", "Margin", "top_margin")
* self.figure_unit_conversion
)
self.bottommargin = (
self._parse_option("Layout", "Margin", "bottom_margin")
* self.figure_unit_conversion
)
self.marginpad = (
self._parse_option("Layout", "Margin", "margin_pad")
* self.figure_unit_conversion
)

self.framewidth = (
self.pagewidth_inch - self.leftmargin - self.rightmargin
)
self.frameheight = (
self.pageheight_inch - self.topmargin - self.bottommargin
)
self._update_marginframe_from_layout()

self.source_path = self._parse_option("Layout", "Margin", "source_path")
self.source_path_position = [
Expand All @@ -618,7 +611,38 @@ def _update_from_layout(self):
# read text
self.configtext = self.config["Text"]

def _text_from_label(self, section, label, txt):
def _update_marginframe_from_layout(self):
"""
Update the mergin frame to what's in the current layout config.
Returns: None

"""
self.constrained_layout = False
self.leftmargin = (
self._parse_option("Layout", "Margin", "left_margin")
* self.figure_unit_conversion
)
self.rightmargin = (
self._parse_option("Layout", "Margin", "right_margin")
* self.figure_unit_conversion
)
self.topmargin = (
self._parse_option("Layout", "Margin", "top_margin")
* self.figure_unit_conversion
)
self.bottommargin = (
self._parse_option("Layout", "Margin", "bottom_margin")
* self.figure_unit_conversion
)
self.marginpad = (
self._parse_option("Layout", "Margin", "margin_pad")
* self.figure_unit_conversion
)

self.framewidth = self.pagewidth_inch - self.leftmargin - self.rightmargin
self.frameheight = self.pageheight_inch - self.topmargin - self.bottommargin

def _text_at_label(self, section, label, txt):

"""
Find label and write text at label position with label font characteristics
Expand Down Expand Up @@ -827,7 +851,7 @@ def _image_from_label(self, label):
ax.imshow(img)
ax.axis("off")

def text_from_label(self, label, txt):
def text_at_label(self, label, txt):
"""
Public function to find label and write text at label position with label font characteristics.
Assumes label is in text section
Expand All @@ -839,7 +863,7 @@ def text_from_label(self, label, txt):
Returns: None

"""
return self._text_from_label("Text", label, txt)
return self._text_at_label("Text", label, txt)

def draw_page(self):
"""
Expand All @@ -859,7 +883,9 @@ def draw_page(self):
fig, ax = plt.subplots(
constrained_layout=self.constrained_layout,
figsize=(self.pagewidth_inch, self.pageheight_inch),
squeeze=False, sharex=self.sharex, sharey=self.sharey,
squeeze=False,
sharex=self.sharex,
sharey=self.sharey,
)

# set the patch here
Expand Down Expand Up @@ -973,19 +999,21 @@ def draw_page(self):
bottom=(self.bottommargin + self.marginpad) / self.pageheight_inch,
top=(self.frameheight + self.bottommargin - self.marginpad)
/ self.pageheight_inch,
hspace=self.hspace, wspace=self.wspace,
hspace=self.hspace,
wspace=self.wspace,
)

# This resets the margins and other parameters to layout
# This resets the margins to the margin layout
if self.marginframe:
self._update_from_layout()
self._update_marginframe_from_layout()

# add any layout set text here
for k in self.config["Text"].keys():
if self._parse_option("Text", k, "text") is not None:
if 'draft' in self._parse_option("Text", k, "text").lower():
if not self.draft: continue
self._text_from_label("Text", k, self._parse_option("Text", k, "text"))
if "draft" in self._parse_option("Text", k, "text").lower():
if not self.draft:
continue
self._text_at_label("Text", k, self._parse_option("Text", k, "text"))

# add any layout set images here
for k in self.config["Images"].keys():
Expand All @@ -999,9 +1027,10 @@ def draw_page(self):
for k in self.config["Watermark"].keys():
if self._parse_option("Watermark", k, "text") is not None:
# check for draft watermark status and whether user has overridden it
if 'draft' in self._parse_option("Watermark", k, "text").lower():
if not self.draft: continue
self._text_from_label(
if "draft" in self._parse_option("Watermark", k, "text").lower():
if not self.draft:
continue
self._text_at_label(
"Watermark", k, self._parse_option("Watermark", k, "text")
)

Expand Down Expand Up @@ -1051,7 +1080,6 @@ def add_subplot(self, direction="left-to-right", pos=None, gs=None, **kwargs):
# self.subplotstartindex = pos
self.currentsubplotindex = pos


if self.direction == "top-to-bottom":
if self.subplotstartindex is None:
pos = [0, 0]
Expand Down Expand Up @@ -1089,7 +1117,7 @@ def add_subplot(self, direction="left-to-right", pos=None, gs=None, **kwargs):
if gs is None:
return self.fig.add_subplot(
self.gs[pos[0], pos[1]],
label="({},{}, {})".format(pos[0], pos[1], self.subplotcounter),
label="({},{}, {})".format(pos[0], pos[1], self.subplotcounter),
**kwargs
)
else:
Expand All @@ -1101,8 +1129,10 @@ def add_subplot(self, direction="left-to-right", pos=None, gs=None, **kwargs):
return self.fig.add_subplot(
gs,
label="({},{}, {})".format(
self.currentsubplotindex[0], self.currentsubplotindex[1],
self.subplotcounter),
self.currentsubplotindex[0],
self.currentsubplotindex[1],
self.subplotcounter,
),
**kwargs
)

Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
.

matplotlib>=2.2.5
configobj==5.0.6
configobj>=5.0.6
pillow>=6.2.2
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ def read(fname):

setup(
name="figpager",
version="0.31",
version="0.32",
author="Eben Pendleton",
author_email="4080051+ebenp@users.noreply.github.com",
url="https://github.com/ebenp/figpager",
Expand Down
Binary file modified tests/out.pdf
Binary file not shown.
Binary file modified tests/out_2.pdf
Binary file not shown.
Binary file modified tests/out_3.pdf
Binary file not shown.
Binary file modified tests/out_4.pdf
Binary file not shown.
Binary file modified tests/out_6.pdf
Binary file not shown.
Binary file modified tests/out_7.pdf
Binary file not shown.
Binary file added tests/out_8.pdf
Binary file not shown.
3 changes: 1 addition & 2 deletions tests/test_0.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
# Test of Report configuration
import os

# backend for display in GitHub Actions
if os.environ.get('DISPLAY','') == '':
print('no display found. Using non-interactive Agg backend')
import matplotlib
matplotlib.use('Agg')

import matplotlib.pyplot as plt
import matplotlib.pyplot as plt # isort: split

from figpager import FigPager

Expand Down
2 changes: 1 addition & 1 deletion tests/test_1.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ def test_main():
ax0.streamplot(X, Y, U, V, density=[0.5, 1])
ax0.set_title("Varying Density")

fp.text_from_label("Figure Title", "Figure 1")
fp.text_at_label("Figure Title", "Figure 1")

# Varying color along a streamline
ax1 = fp.add_subplot()
Expand Down
2 changes: 1 addition & 1 deletion tests/test_5.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ def test_main():
ax0.streamplot(X, Y, U, V, density=[0.5, 1])
ax0.set_title("Varying Density")

fp.text_from_label("Figure Title", "Figure 1")
fp.text_at_label("Figure Title", "Figure 1")

# Varying color along a streamline
ax1 = fp.add_subplot()
Expand Down
2 changes: 1 addition & 1 deletion tests/test_6.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ def test_main():
ax0.streamplot(X, Y, U, V, density=[0.5, 1])
ax0.set_title("Varying Density")

fp.text_from_label("Figure Title", "Figure 1")
fp.text_at_label("Figure Title", "Figure 1")

# Varying color along a streamline
ax1 = fp.add_subplot()
Expand Down
2 changes: 1 addition & 1 deletion tests/test_7.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ def test_main():
ax0.streamplot(X, Y, U, V, density=[0.5, 1])
ax0.set_title("Varying Density")

fp.text_from_label("Figure Title", "Figure 1")
fp.text_at_label("Figure Title", "Figure 1")

# Varying color along a streamline
ax1 = fp.add_subplot()
Expand Down
Loading