Skip to content

Commit

Permalink
Plots svg (#59)
Browse files Browse the repository at this point in the history
* figures to svg, drop mpld3

* drop branca

* pydocstyle

* pylint

* pylint

* maps popup figsize keyword

* plt close

* fix output
  • Loading branch information
mhallipelto authored Apr 22, 2021
1 parent ead30db commit 2d25fcd
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 68 deletions.
13 changes: 7 additions & 6 deletions pyinfraformat/core/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -452,22 +452,23 @@ def _get_dataframe(self, update=False):

return self._dataframe

def plot(self, backend="matplotlib"):
def plot(self, output="figure", figsize=(4, 4)):
"""Plot a diagram of a sounding with matplotlib.
Parameters
----------
backend : str
Backend to plot with
possible values 'mpld3' and 'matplotlib'
output : str
Possible values: ['figure', 'svg']
figsize : tuple
figure size in inches
Returns
-------
figure : matplotlib figure or mpld3 html
figure : matplotlib figure or svg
"""
from ..plots.holes import plot_hole

return plot_hole(self, backend)
return plot_hole(self, output, figsize)


class FileHeader:
Expand Down
68 changes: 16 additions & 52 deletions pyinfraformat/plots/holes.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
"""Plot diagrams for a single hole."""
import gc
import json
import io
import logging
from datetime import datetime

import matplotlib.dates as mdates
import matplotlib.patches as patches
import matplotlib.pyplot as plt
import mpld3
import numpy as np
import pandas as pd

Expand All @@ -18,30 +17,6 @@
logger = logging.getLogger("pyinfraformat")


def convert_numpy(obj):
"""Convert numpy float or int to python."""
if isinstance(
obj,
(
np.int_,
np.intc,
np.intp,
np.int8,
np.int16,
np.int32,
np.int64,
np.uint8,
np.uint16,
np.uint32,
np.uint64,
),
):
return int(obj)
elif isinstance(obj, (np.float_, np.float16, np.float32, np.float64)):
return float(obj)
return json.JSONEncoder().default(obj)


def strip_date(x):
"""Strip str date to datetime."""
x = str(x)
Expand All @@ -63,33 +38,20 @@ def fig_to_hmtl(fig, clear_memory=True):
Parameters
----------
fig: matplotlib figure
clear_memory: bool
Returns
-------
html
"""
# mpld3.plugins.clear(fig)
html = mpld3.fig_to_html(
fig, no_extras=True, template_type="simple", d3_url=r"https://d3js.org/d3.v3.min.js"
)
emtpy_html = (
html[: html.find("{", html.find("{") + 1)]
+ "{replace}"
+ html[html.rfind("}", 0, html.rfind("}") - 1) + 1 :]
)
figure_dict = mpld3.fig_to_dict(fig)

left, _ = figure_dict["axes"]
del left["axes"][1]

figure_json = json.dumps(figure_dict, default=convert_numpy)

str_io = io.StringIO()
fig.savefig(str_io, format="svg")
str_io.seek(0)
if clear_memory:
fig.clear()
plt.close()
gc.collect()

return emtpy_html.replace("{replace}", figure_json)
return str_io.read()


def plot_po(one_survey):
Expand Down Expand Up @@ -500,19 +462,20 @@ def plot_vp(one_survey):
return fig


def plot_hole(one_survey, backend="matplotlib"):
def plot_hole(one_survey, output="figure", figsize=(4, 4)):
"""Plot a diagram of a sounding with matplotlib.
Parameters
----------
one_survey : hole object
backend : str
Backend to plot with
possible values 'mpld3' and 'matplotlib'
output : str
Possible values: ['figure', 'svg']
figsize : tuple
figure size in inches
Returns
-------
figure : matplotlib figure or mpld3 html
figure : figure or svg
"""

def _plot_hole(one_survey):
Expand All @@ -539,6 +502,7 @@ def _plot_hole(one_survey):
else:
raise NotImplementedError('Hole object "{}" not supported'.format(hole_type))
fig.tight_layout()
fig.set_size_inches(figsize)
return fig

try:
Expand All @@ -548,9 +512,9 @@ def _plot_hole(one_survey):
plt.close()
raise

if backend == "matplotlib":
if output == "figure":
return fig
elif backend == "mpld3":
elif output == "svg":
return fig_to_hmtl(fig)
else:
raise NotImplementedError("Plotting backend {} not implemented".format(backend))
raise NotImplementedError("Plotting backend {} not implemented".format(output))
12 changes: 5 additions & 7 deletions pyinfraformat/plots/maps.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
from itertools import cycle
from pathlib import Path

import branca
import folium
import numpy as np
from folium.plugins import MarkerCluster, MeasureControl, MousePosition
Expand Down Expand Up @@ -58,14 +57,16 @@
}


def plot_map(holes, render_holes=True):
def plot_map(holes, render_holes=True, popup_size=(3, 3)):
"""Plot a leaflet map from holes with popup hole plots.
Parameters
----------
holes : holes object
render_holes : bool
Render popup diagrams for holes
popup_size : tuple
size in inches of popup figure
Returns
-------
Expand Down Expand Up @@ -185,8 +186,6 @@ def plot_map(holes, render_holes=True):
clust_icon_kwargs[key] = dict(color=color, icon="")
map_fig.add_child(hole_clusters[key])

width = 300
height = 300
for i, hole in enumerate(holes_filtered):
x, y = [hole.header.XY["X"], hole.header.XY["Y"]]
x, y = project_points(x, y, input_epsg)
Expand All @@ -197,9 +196,8 @@ def plot_map(holes, render_holes=True):
key = "Missing survey abbreviation"
if render_holes and key != "Missing survey abbreviation":
try:
html = plot_hole(hole, backend="mpld3")
iframe = branca.element.IFrame(html=html, width=width, height=height + 5)
popup = folium.Popup(iframe, max_width=width)
hole_svg = plot_hole(hole, output="svg", figsize=popup_size)
popup = folium.Popup(hole_svg)
icon = get_icon(key, clust_icon_kwargs)
folium.Marker(location=[x, y], popup=popup, icon=icon).add_to(hole_clusters[key])

Expand Down
4 changes: 1 addition & 3 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
branca
chardet
folium
numpy
matplotlib<3.3.3
mpld3<=0.3
matplotlib
pandas
pyproj
xmltodict
Expand Down

0 comments on commit 2d25fcd

Please sign in to comment.