Skip to content

Commit 21b18e8

Browse files
authored
Merge pull request #300 from statisticsnorway/map-hatches
docs
2 parents 7d6c2ee + 943e10a commit 21b18e8

File tree

6 files changed

+50
-39
lines changed

6 files changed

+50
-39
lines changed

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tool.poetry]
22
name = "ssb-sgis"
3-
version = "1.2.13"
3+
version = "1.2.14"
44
description = "GIS functions used at Statistics Norway."
55
authors = ["Morten Letnes <morten.letnes@ssb.no>"]
66
license = "MIT"

src/sgis/maps/legend.py

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,8 @@ def _actually_add_legend(self, ax: matplotlib.axes.Axes) -> matplotlib.axes.Axes
330330
framealpha=self.framealpha,
331331
edgecolor=self.edgecolor,
332332
labelspacing=self.labelspacing,
333+
facecolor=self.facecolor,
334+
labelcolor=self.labelcolor,
333335
**self.kwargs,
334336
)
335337

@@ -344,16 +346,22 @@ def _get_best_legend_position(
344346
minx, miny, maxx, maxy = gdf.total_bounds
345347
diffx = maxx - minx
346348
diffy = maxy - miny
347-
349+
if diffx > 10000 and diffy > 10000:
350+
gridsize = (diffy + diffx) // 1000
351+
if diffx > 1000 and diffy > 1000:
352+
gridsize = (diffy + diffx) // 100
353+
if diffx > 100 and diffy > 100:
354+
gridsize = (diffy + diffx) // 10
355+
else:
356+
gridsize = 30
348357
points = pd.concat(
349358
[
350-
points_in_bounds(gdf, 30),
359+
points_in_bounds(gdf, gridsize),
351360
bounds_to_points(gdf)
352361
.geometry.explode(ignore_index=True)
353362
.to_frame("geometry"),
354363
]
355364
)
356-
357365
gdf = gdf.loc[:, ~gdf.columns.str.contains("index|level_")]
358366
joined = points.sjoin_nearest(gdf, distance_col="nearest")
359367

src/sgis/maps/thematicmap.py

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -253,18 +253,13 @@ def __init__(
253253
self._dark = self._dark or black
254254

255255
if not self.cmap and not self._is_categorical:
256-
self._choose_cmap()
256+
self._choose_cmap(**kwargs)
257257

258258
if not legend:
259259
self.legend = None
260260
else:
261261
self._create_legend()
262262

263-
self._dark_or_light()
264-
265-
if cmap:
266-
self._cmap = cmap
267-
268263
new_kwargs = {}
269264
for key, value in self.kwargs.items():
270265
if key not in MAP_KWARGS:
@@ -286,6 +281,11 @@ def __init__(
286281
except Exception:
287282
setattr(self.legend, f"_{key}", value)
288283

284+
self._dark_or_light()
285+
286+
if cmap:
287+
self._cmap = cmap
288+
289289
self.bounds = (
290290
to_bbox(bounds) if bounds is not None else to_bbox(self._gdf.total_bounds)
291291
)
@@ -589,16 +589,16 @@ def _create_legend(self) -> None:
589589
else:
590590
self.legend = ContinousLegend(title=self._column, size=self._size)
591591

592-
def _choose_cmap(self) -> None:
592+
def _choose_cmap(self, **kwargs) -> None:
593593
"""Kwargs is to catch start and stop points for the cmap in __init__."""
594594
if self._dark:
595595
self._cmap = "viridis"
596-
self.cmap_start = 0
597-
self.cmap_stop = 256
596+
self.cmap_start = self.kwargs.pop("cmap_start", 0)
597+
self.cmap_stop = self.kwargs.pop("cmap_stop", 256)
598598
else:
599599
self._cmap = "RdPu"
600-
self.cmap_start = 23
601-
self.cmap_stop = 256
600+
self.cmap_start = self.kwargs.pop("cmap_start", 23)
601+
self.cmap_stop = self.kwargs.pop("cmap_stop", 256)
602602

603603
def _make_bin_value_dict(self, gdf: GeoDataFrame, classified: np.ndarray) -> dict:
604604
"""Dict with unique values of all bins. Used in labels in ContinousLegend."""
@@ -609,8 +609,6 @@ def _make_bin_value_dict(self, gdf: GeoDataFrame, classified: np.ndarray) -> dic
609609
return bins_unique_values
610610

611611
def _actually_add_background(self) -> None:
612-
# self.ax.set_xlim([self.minx - self.diffx * 0.03, self.maxx + self.diffx * 0.03])
613-
# self.ax.set_ylim([self.miny - self.diffy * 0.03, self.maxy + self.diffy * 0.03])
614612
self._background_gdfs.plot(
615613
ax=self.ax, color=self.bg_gdf_color, **self.bg_gdf_kwargs
616614
)
@@ -632,13 +630,14 @@ def _dark_or_light(self) -> None:
632630
)
633631
self.nan_color = "#666666" if self._nan_color_was_none else self.nan_color
634632
if not self._is_categorical:
635-
self.change_cmap("viridis")
633+
self._cmap = self.kwargs.get("cmap", "viridis")
636634

637635
if self.legend is not None:
638636
for key, color in {
639637
"facecolor": "#0f0f0f",
640638
"labelcolor": "#fefefe",
641639
"title_color": "#fefefe",
640+
"edgecolor": "#0f0f0f",
642641
}.items():
643642
setattr(self.legend, key, color)
644643

@@ -650,13 +649,14 @@ def _dark_or_light(self) -> None:
650649
)
651650
self.nan_color = "#c2c2c2" if self._nan_color_was_none else self.nan_color
652651
if not self._is_categorical:
653-
self.change_cmap("RdPu", start=23)
652+
self._cmap = self.kwargs.get("cmap", "RdPu")
654653

655654
if self.legend is not None:
656655
for key, color in {
657656
"facecolor": "#fefefe",
658657
"labelcolor": "#0f0f0f",
659658
"title_color": "#0f0f0f",
659+
"edgecolor": "#0f0f0f",
660660
}.items():
661661
setattr(self.legend, key, color)
662662

src/sgis/networkanalysis/_get_route.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import joblib
44
import pandas as pd
5+
import shapely
56
from geopandas import GeoDataFrame
67
from igraph import Graph
78
from pandas import DataFrame
@@ -116,8 +117,8 @@ def _get_route(
116117
results: DataFrame = pd.concat(resultlist)
117118
assert list(results.columns) == ["origin", "destination"], list(results.columns)
118119
lines: GeoDataFrame = _get_line_geometries(results, roads, weight)
120+
lines.geometry = shapely.force_2d(lines.geometry)
119121
lines = lines.dissolve(by=["origin", "destination"], aggfunc="sum", as_index=False)
120-
121122
return lines[["origin", "destination", weight, "geometry"]]
122123

123124

src/sgis/networkanalysis/_service_area.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,10 +129,12 @@ def _service_area(
129129

130130
service_areas.append(edges_within)
131131

132-
return pd.concat(
132+
service_areas = pd.concat(
133133
service_areas,
134134
ignore_index=True,
135135
)
136+
service_areas.geometry = force_2d(service_areas.geometry)
137+
return service_areas
136138

137139

138140
def _part_of_edge_within(distance_df, nodes_within_break, directed):

src/sgis/networkanalysis/networkanalysis.py

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
from igraph import Graph
1818
from pandas import DataFrame
1919
from pandas import MultiIndex
20+
from shapely import force_2d
2021

2122
from ..geopandas_tools.general import _push_geom_col
2223
from ._get_route import _get_k_routes
@@ -34,9 +35,20 @@
3435
class NetworkAnalysis:
3536
"""Class for doing network analysis.
3637
37-
The class takes a GeoDataFrame of line geometries and rules for the analyses,
38-
and holds methods for doing network analysis based on GeoDataFrames of origin
39-
and destination points.
38+
Args:
39+
network: A GeoDataFrame of line geometries.
40+
rules: The rules for the analysis, either as an instance of
41+
NetworkAnalysisRules or a dictionary with the parameters
42+
as keys.
43+
log: If True (default), a DataFrame with information about each
44+
analysis run will be stored in the 'log' attribute.
45+
detailed_log: If True, the log DataFrame will include columns for
46+
all arguments passed to the analysis method, plus standard deviation and
47+
percentiles (25th, 50th, 75th) of the weight column in the results.
48+
Defaults to False.
49+
50+
The class implements methods for doing network analysis based on
51+
GeoDataFrames of origin and destination points.
4052
4153
The 'od_cost_matrix' method is the fastest, and returns a DataFrame with only
4254
indices and travel costs between each origin-destination pair.
@@ -96,21 +108,7 @@ def __init__(
96108
log: bool = True,
97109
detailed_log: bool = False,
98110
) -> None:
99-
"""Initialise NetworkAnalysis instance.
100-
101-
Args:
102-
network: A GeoDataFrame of line geometries.
103-
rules: The rules for the analysis, either as an instance of
104-
NetworkAnalysisRules or a dictionary with the parameters
105-
as keys.
106-
log: If True (default), a DataFrame with information about each
107-
analysis run will be stored in the 'log' attribute.
108-
detailed_log: If True, the log DataFrame will include columns for
109-
all arguments passed to the analysis method, plus standard deviation and
110-
percentiles (25th, 50th, 75th) of the weight column in the results.
111-
Defaults to False.
112-
113-
"""
111+
"""Initialise NetworkAnalysis instance."""
114112
if not isinstance(rules, NetworkAnalysisRules):
115113
rules = NetworkAnalysisRules(**rules)
116114

@@ -647,6 +645,8 @@ def multiindex_mapper(x: tuple[int, int]) -> tuple[int, int]:
647645
frequency_col
648646
)
649647

648+
results.geometry = force_2d(results.geometry)
649+
650650
if self.rules.split_lines:
651651
self._unsplit_network()
652652

0 commit comments

Comments
 (0)