From 989c44b484338fe1ee6aa488193ae6557af4fca4 Mon Sep 17 00:00:00 2001 From: Colin Carroll Date: Sun, 20 Apr 2025 08:56:27 -0400 Subject: [PATCH] Revert "Square is deprecated." --- .coverage | Bin 53248 -> 0 bytes ridge_map.egg-info/PKG-INFO | 365 ------------------------ ridge_map.egg-info/SOURCES.txt | 11 - ridge_map.egg-info/dependency_links.txt | 1 - ridge_map.egg-info/requires.txt | 4 - ridge_map.egg-info/top_level.txt | 1 - ridge_map/ridge_map.py | 64 ++--- 7 files changed, 27 insertions(+), 419 deletions(-) delete mode 100644 .coverage delete mode 100644 ridge_map.egg-info/PKG-INFO delete mode 100644 ridge_map.egg-info/SOURCES.txt delete mode 100644 ridge_map.egg-info/dependency_links.txt delete mode 100644 ridge_map.egg-info/requires.txt delete mode 100644 ridge_map.egg-info/top_level.txt diff --git a/.coverage b/.coverage deleted file mode 100644 index 09adc1eaba5d7f26ef5687d0875ebbae81831db9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 53248 zcmeI)&2QUe90zc}q{)&dcxakJsir;`Xsh*Q6^HSrZ3TLmm^2213lg4_JZU{*JF}gx zJwTTYX%dJlCj>YC1UNDz{(y1iG;TY=WlTb2g5S@NotLetHZ*B!_*zZs*w6F$`F;Gn z#7XP-&Yf{%DVjm(Ik9+2JE-Zpc1j3M(~9({&?8$4w35qS&~JTUebj1ETiX1hVtt^M z^IvM#N0qbIV)^UJi<7^Uz2fJS-xQo;opxY>00bZaf&aHa_guM9oto0GeiA#imW)HE zE<^QPdGp=1)$?oO{OTKL)`Z$7=1PK=#YM3y!r-!K%TP4kmK3hvaO+O&`s*UzkXhRYDE+#OR4wM*#(Zi1+D@rZJ#7hyf1dTzxk+A#2z<3O}rKMB*1+}I6#A-80`6U)Y~0WL6Fwh-Q6G*s3F4(Ni) znI3CEr=NM3oN4kjbCW9P2N`QWBOjVFCw2BaUX92vcDy#99Lk{%90#Lvj>;PcX|Ruc zZgx4B{dk8?XGYFvRORaU?xl|Go%{vS&$*C<;Rg$XgP<1h!eqYs${}5&Rw=ilOD%f8 zWjmcXNM74?^6eFRDu4FufkJg=M!$Y3X(-HN*W5VjtrUkEO>gsvro;P3w;S#y!;OS{ zQL80_X3}Liw@@dCTJvC^Sy< z?D%!=DiOy}4>o1!tjnczuNoGfc0;13vr^1g*JegFon8~LS9+_Z?o_@|ou1aO7L#U_ zo~`s(VW=RI(sEuInXWS z3f04h^{(m>JTCELVkijS((eKfOazZ!{k9Wth==RWo2lZn6Zz_EheuVMt6;D2bN_REO2xs3JA*`!X{#prmq)Cu{G~RTaH*ctP~DwR%0P*iH{?UbsoCf)Czi46Nx?~y$|Mcz zvJ;7VC}}6nrSr4qUd@2dmc7Eye3g8F-^z7o^g{LMQN7zqJEIzB?1(0H&&jHtzBGm! z$pbt4?d2>Dxb$vku${2o00+NRN8rItoxz$?$Wo>6bxQMmfv;QlH2T2;0SG_<0uX=z z1Rwwb2tWV=5P-n=37EQ}7x?<$uzu65Kj;Yy1Rwwb2tWV=5P$##AOHafKmY>!Q=n{^ zN385mJdRnqIbBWv2;lhA%S*>f6qRA!)~wsspZhaF)EWX1fB*y_009U<00Izz00bZa zflQ!m9?`Q;0gRG4T}(d&P~ZRWXx0sDCrgXp5P$##AOHafKmY;|fB*y_009U*QGt_2 zPV1V>??-g21G=+Hi*61S2Cdd|I}9$$dK@i>Zev~Ap3~lKjqZ1FLZ<@s$1K3MUEhsu zoARsg|F3A)Pu7(u8W{?M00bZa0SG_<0uX=z1Rwwb2tc4Ga4Od|ANTUT_n81)zZ)lV zUA_3o4oZ7>06&)y?(6ppy(n+~ldRwTedmYG``-o=dahV} z=6Uu1|93R&o^_{}6e|#b00bZa0SG_<0uX=z1Rwwb2<&@-Jbh%K8%B;k07$<7*ADLc zkPrX_AOHafKmY;|fB*y_009U<00Mgm@b~|?{@()#yC47o2tWV=5P$##AOHafKmY<` wAfW#L|1SUi|J^YN2O&TJ0uX=z1Rwwb2tWV=5P$##AkY&q4Z8Jza{vE-0Yzw?AOHXW diff --git a/ridge_map.egg-info/PKG-INFO b/ridge_map.egg-info/PKG-INFO deleted file mode 100644 index bf81cb4..0000000 --- a/ridge_map.egg-info/PKG-INFO +++ /dev/null @@ -1,365 +0,0 @@ -Metadata-Version: 2.2 -Name: ridge_map -Version: 0.0.6 -Summary: 1d lines, 3d maps -Home-page: https://github.com/ColCarroll/ridge_map -Author: Colin Carroll -Author-email: colcarroll@gmail.com -License: MIT -Classifier: Development Status :: 3 - Alpha -Classifier: Intended Audience :: Developers -Classifier: License :: OSI Approved :: MIT License -Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3.5 -Classifier: Programming Language :: Python :: 3.6 -Classifier: Programming Language :: Python :: 3.7 -Description-Content-Type: text/markdown -License-File: LICENSE -Requires-Dist: SRTM.py -Requires-Dist: numpy -Requires-Dist: matplotlib -Requires-Dist: scikit-image>=0.14.2 -Dynamic: author -Dynamic: author-email -Dynamic: classifier -Dynamic: description -Dynamic: description-content-type -Dynamic: home-page -Dynamic: license -Dynamic: requires-dist -Dynamic: summary - -ridge_map -========= -![Build status](https://github.com/ColCarroll/ridge_map/actions/workflows/build.yml/badge.svg) - -*Ridge plots of ridges* ------------------------ - -A library for making ridge plots of... ridges. Choose a location, get an elevation map, and tinker with it to make something beautiful. Heavily inspired from [Zach Cole's beautiful art](https://twitter.com/ZachACole/status/1121554541101477889), [Jake Vanderplas' examples](https://github.com/jakevdp/altair-examples/blob/master/notebooks/PulsarPlot.ipynb), and Joy Division's [1979 album "Unknown Pleasures"](https://gist.github.com/ColCarroll/68e29c92b766418b0a4497b4eb2ecba4). - -Uses [matplotlib](https://matplotlib.org/), [SRTM.py](https://github.com/tkrajina/srtm.py), [numpy](https://www.numpy.org/), and [scikit-image](https://scikit-image.org/) (for lake detection). - -Installation ------------- - -Available on [PyPI](https://pypi.org/project/ridge-map/): - -```bash -pip install ridge_map -``` - -Or live on the edge and install from github with - -```bash -pip install git+https://github.com/colcarroll/ridge_map.git -``` - -You can also make a copy of [this colab](https://colab.research.google.com/drive/1ntwd73haePt3OS5ysz4yGSlhmUecY24O?usp=sharing). - -Want to help? -------------- - -- I feel like I am missing something easy or obvious with lake/road/river/ocean detection, but what I've got gets me most of the way there. If you hack on the `RidgeMap.preprocessor` method and find something nice, I would love to hear about it! -- Did you make a cool map? Open an issue with the code and I will add it to the examples. - -Examples --------- - -The API allows you to download the data once, then edit the plot yourself, -or allow the default processor to help you. - -### New Hampshire by default - -Plotting with all the defaults should give you a map of my favorite mountains. - -```python -from ridge_map import RidgeMap - -RidgeMap().plot_map() -``` - -![png](https://github.com/ColCarroll/ridge_map/blob/main/examples/white_mountains.png?raw=true) - -### Download once and tweak settings - -First you download the elevation data to get an array with shape -`(num_lines, elevation_pts)`, then you can use the preprocessor -to automatically detect lakes, rivers, and oceans, and scale the elevations. -Finally, there are options to style the plot - -```python -rm = RidgeMap((11.098251,47.264786,11.695633,47.453630)) -values = rm.get_elevation_data(num_lines=150) -values=rm.preprocess( - values=values, - lake_flatness=2, - water_ntile=10, - vertical_ratio=240) -rm.plot_map(values=values, - label='Karwendelgebirge', - label_y=0.1, - label_x=0.55, - label_size=40, - linewidth=1) -``` - -![png](https://github.com/ColCarroll/ridge_map/blob/main/examples/karwendelgebirge.png?raw=true) - -### Plot with colors! - -If you are plotting a town that is super into burnt orange for whatever -reason, you can respect that choice. - -```python -rm = RidgeMap((-97.794285,30.232226,-97.710171,30.334509)) -values = rm.get_elevation_data(num_lines=80) -rm.plot_map(values=rm.preprocess(values=values, water_ntile=12, vertical_ratio=40), - label='Austin\nTexas', - label_x=0.75, - linewidth=6, - line_color='orange') -``` - -![png](https://github.com/ColCarroll/ridge_map/blob/main/examples/austin.png?raw=true) - -### Plot with even more colors! - -The line color accepts a [matplotlib colormap](https://matplotlib.org/gallery/color/colormap_reference.html#sphx-glr-gallery-color-colormap-reference-py), so really feel free to go to town. - -```python -rm = RidgeMap((-123.107300,36.820279,-121.519775,38.210130)) -values = rm.get_elevation_data(num_lines=150) -rm.plot_map(values=rm.preprocess(values=values, lake_flatness=3, water_ntile=50, vertical_ratio=30), - label='The Bay\nArea', - label_x=0.1, - line_color = plt.get_cmap('spring')) -``` - -![png](https://github.com/ColCarroll/ridge_map/blob/main/examples/san_francisco.png?raw=true) - -### Plot with custom fonts and elevation colors! - -You can find a good font [from Google](https://fonts.google.com/), and then get the path to the ttf file [in the github repo](https://github.com/google/fonts/tree/master/ofl). - -If you pass a matplotlib colormap, you can specify `kind="elevation"` to color tops of mountains different from bottoms. `ocean`, `gnuplot`, and `bone` look nice. - -```python -from ridge_map import FontManager - -font = FontManager('https://github.com/google/fonts/blob/main/ofl/uncialantiqua/UncialAntiqua-Regular.ttf?raw=true') -rm = RidgeMap((-156.250305,18.890695,-154.714966,20.275080), font=font.prop) - -values = rm.get_elevation_data(num_lines=100) -rm.plot_map(values=rm.preprocess(values=values, lake_flatness=2, water_ntile=10, vertical_ratio=240), - label="Hawai'i", - label_y=0.85, - label_x=0.7, - label_size=60, - linewidth=2, - line_color=plt.get_cmap('ocean'), - kind='elevation') -``` - -![png](https://github.com/ColCarroll/ridge_map/blob/main/examples/hawaii.png?raw=true) - -### How do I find a bounding box? - -I have been using [this website](http://bboxfinder.com). I find an area I like, draw a rectangle, then copy and paste the coordinates into the `RidgeMap` constructor. - -```python -rm = RidgeMap((-73.509693,41.678682,-73.342838,41.761581)) -values = rm.get_elevation_data() -rm.plot_map(values=rm.preprocess(values=values, lake_flatness=2, water_ntile=2, vertical_ratio=60), - label='Kent\nConnecticut', - label_y=0.7, - label_x=0.65, - label_size=40) -``` - -![png](https://github.com/ColCarroll/ridge_map/blob/main/examples/kent.png?raw=true) - -### What about really flat areas? - -You might really have to tune the `water_ntile` and `lake_flatness` to get the water right. You can set them to 0 if you do not want any water marked. - -```python -rm = RidgeMap((-71.167374,42.324286,-70.952454, 42.402672)) -values = rm.get_elevation_data(num_lines=50) -rm.plot_map(values=rm.preprocess(values=values, lake_flatness=4, water_ntile=30, vertical_ratio=20), - label='Cambridge\nand Boston', - label_x=0.75, - label_size=40, - linewidth=1) -``` - -![png](https://github.com/ColCarroll/ridge_map/blob/main/examples/boston.png?raw=true) - -### Can I change the angle? - -Yes, you can change the angle at which you look at the map. South to North is 0 degrees, East to West is 90 degrees and so forth with the rest of the compass. I really recommend playing around with this setting because of the really cool maps it can generate. - -Play around with `interpolation`, `lock_rotation`, and `crop` to polish out the map. - -```python -rm = RidgeMap((-124.848974,46.292035,-116.463262,49.345786)) -values = rm.get_elevation_data(elevation_pts=300, num_lines=300, viewpoint_angle=11) -values=rm.preprocess( - values=values, - lake_flatness=2, - water_ntile=10, - vertical_ratio=240 -) -rm.plot_map(values=values, - label='Washington', - label_y=0.8, - label_x=0.05, - label_size=40, - linewidth=2 -) -``` - -![png](/examples/washington.png?raw=true) -![gif](/examples/washington.gif?raw=true) - -### What about Walden Pond? - -It is that pleasant kettle pond in the bottom right of this map, looking entirely comfortable with its place in Western writing and thought. - -```python -rm = RidgeMap((-71.418858,42.427511,-71.310024,42.481719)) -values = rm.get_elevation_data(num_lines=100) -rm.plot_map(values=rm.preprocess(values=values, water_ntile=15, vertical_ratio=30), - label='Concord\nMassachusetts', - label_x=0.1, - label_size=30) -``` - -![png](https://github.com/ColCarroll/ridge_map/blob/main/examples/concord.png?raw=true) - -### Do you play nicely with other matplotlib figures? - -Of course! If you really want to put a stylized elevation map in a scientific plot you are making, I am not going to stop you, and will actually make it easier for you. Just pass an argument for `ax` to `RidgeMap.plot_map`. - -```python -import numpy as np -fig, axes = plt.subplots(ncols=2, figsize=(20, 5)) -x = np.linspace(-2, 2) -y = x * x - -axes[0].plot(x, y, 'o') - -rm = RidgeMap() -rm.plot_map(label_size=24, background_color=(1, 1, 1), ax=axes[1]) -``` - -![png](https://github.com/ColCarroll/ridge_map/blob/main/examples/multiaxis.png?raw=true) - -User Examples -------------- - -### Annotating, changing background color, custom text - -This example shows how to annotate a lat/long on the map, and updates the color of the label text to allow for a dark background. Thanks to [kratsg](https://github.com/kratsg) for contributing. - -```python -import matplotlib -import matplotlib.pyplot as plt -import numpy as np - -bgcolor = np.array([65,74,76])/255. - -scipp = (-122.060510, 36.998776) -rm = RidgeMap((-122.087116,36.945365,-121.999226,37.023250)) -scipp_coords = ((scipp[0] - rm.longs[0])/(rm.longs[1] - rm.longs[0]),(scipp[1] - rm.lats[0])/(rm.lats[1] - rm.lats[0])) - -values = rm.get_elevation_data(num_lines=150) -ridges = rm.plot_map(values=rm.preprocess(values=values, - lake_flatness=1, - water_ntile=0, - vertical_ratio=240), - label='Santa Cruz\nMountains', - label_x=0.75, - label_y=0.05, - label_size=36, - kind='elevation', - linewidth=1, - background_color=bgcolor, - line_color = plt.get_cmap('cool')) - -# Bit of a hack to update the text label color -for child in ridges.get_children(): - if isinstance(child, matplotlib.text.Text) and 'Santa Cruz' in child._text: - label_artist = child - break -label_artist.set_color('white') - -ridges.text(scipp_coords[0]+0.005, scipp_coords[1]+0.005, 'SCIPP', - fontproperties=rm.font, - size=20, - color="white", - transform=ridges.transAxes, - verticalalignment="bottom", - zorder=len(values)+10) - -ridges.plot(*scipp_coords, 'o', - color='white', - transform=ridges.transAxes, - ms=6, - zorder=len(values)+10) -``` - -#### Updated Annotation and Custom Text Color -The above code still works, but now there is a simplified method (Shown Below) that will produce the same image. - -```python -import matplotlib.pyplot as plt -import numpy as np - -from ridge_map import RidgeMap - -bgcolor = np.array([65,74,76])/255. - -rm = RidgeMap((-122.087116,36.945365,-121.999226,37.023250)) -values = rm.get_elevation_data(num_lines=150) -values = rm.preprocess( - values=values, - lake_flatness=1, - water_ntile=0, - vertical_ratio=240 -) - -rm.plot_map( - values=values, - label='Santa Cruz\nMountains', - label_x=0.75, - label_y=0.05, - label_size=36, - label_color='white', - kind='elevation', - linewidth=1, - background_color=bgcolor, - line_color = plt.get_cmap('cool') -) - -rm.plot_annotation( - label='SCIPP', - coordinates=(-122.060510, 36.998776), - x_offset=0.005, - y_offset=0.005, - label_size=20, - annotation_size=6, - color='white', - background=False -) -``` -![png](https://github.com/ColCarroll/ridge_map/blob/main/examples/santa_cruz.png?raw=true) - -Elevation Data --------------- - -Elevation data used by `ridge_map` comes from NASA's [Shuttle Radar Topography Mission](https://www2.jpl.nasa.gov/srtm/) (SRTM), high resolution topographic data collected in 2000, and released in 2015. SRTM data are sampled at a resolution of 1 arc-second (about 30 meters). SRTM data is provided to `ridge_map` via the python package `SRTM.py` ([link](https://github.com/tkrajina/srtm.py)). SRTM data is not available for latitudes greater than N 60° or less than S 60°: - - - -![gif](https://www2.jpl.nasa.gov/srtm/images/SRTM_2-24-2016.gif) diff --git a/ridge_map.egg-info/SOURCES.txt b/ridge_map.egg-info/SOURCES.txt deleted file mode 100644 index 36b067a..0000000 --- a/ridge_map.egg-info/SOURCES.txt +++ /dev/null @@ -1,11 +0,0 @@ -LICENSE -README.md -setup.py -ridge_map/__init__.py -ridge_map/ridge_map.py -ridge_map.egg-info/PKG-INFO -ridge_map.egg-info/SOURCES.txt -ridge_map.egg-info/dependency_links.txt -ridge_map.egg-info/requires.txt -ridge_map.egg-info/top_level.txt -test/test_ridge_map.py \ No newline at end of file diff --git a/ridge_map.egg-info/dependency_links.txt b/ridge_map.egg-info/dependency_links.txt deleted file mode 100644 index 8b13789..0000000 --- a/ridge_map.egg-info/dependency_links.txt +++ /dev/null @@ -1 +0,0 @@ - diff --git a/ridge_map.egg-info/requires.txt b/ridge_map.egg-info/requires.txt deleted file mode 100644 index 6578952..0000000 --- a/ridge_map.egg-info/requires.txt +++ /dev/null @@ -1,4 +0,0 @@ -SRTM.py -numpy -matplotlib -scikit-image>=0.14.2 diff --git a/ridge_map.egg-info/top_level.txt b/ridge_map.egg-info/top_level.txt deleted file mode 100644 index 9071f8e..0000000 --- a/ridge_map.egg-info/top_level.txt +++ /dev/null @@ -1 +0,0 @@ -ridge_map diff --git a/ridge_map/ridge_map.py b/ridge_map/ridge_map.py index 4e7f68b..87a9c05 100644 --- a/ridge_map/ridge_map.py +++ b/ridge_map/ridge_map.py @@ -8,7 +8,7 @@ import matplotlib.pyplot as plt import numpy as np from skimage.filters import rank -from skimage.morphology import footprint_rectangle +from skimage.morphology import square from skimage.util import img_as_ubyte from scipy.ndimage import rotate @@ -91,15 +91,14 @@ def longs(self): """Bottom and top longitude of bounding box.""" return (self.bbox[0], self.bbox[2]) - # pylint: disable=too-many-arguments,too-many-positional-arguments def get_elevation_data( - self, - num_lines=80, - elevation_pts=300, - viewpoint_angle=0, + self, + num_lines=80, + elevation_pts=300, + viewpoint_angle=0, crop=False, - interpolation=0, - lock_resolution=False, + interpolation=0, + lock_resolution=False ): """Fetch elevation data and return a numpy array. @@ -115,29 +114,25 @@ def get_elevation_data( crop : bool If the corners are cropped when rotating interpolation : int in [0, 5] - The level of interpolation. Can smooth out sharp edges, especially + The level of interpolation. Can smooth out sharp edges, especially when rotating. Above 1 tends to lead to an all NaN graph. lock_resolution : bool - Locks the resolution during rotation, ensuring consistent rotation - deltas but producing potential scaling artifacts. These artifacts + Locks the resolution during rotation, ensuring consistent rotation + deltas but producing potential scaling artifacts. These artifacts can be reduced by setting num_lines = elevation_pts. Returns ------- np.ndarray """ - if ( - 45 < (viewpoint_angle % 360) < 135 or 225 < (viewpoint_angle % 360) < 315 - ) and not lock_resolution: + if (45 < (viewpoint_angle % 360) < 135 or 225 < (viewpoint_angle % 360) < 315) and not lock_resolution: num_lines, elevation_pts = elevation_pts, num_lines - + values = self._srtm_data.get_image( (elevation_pts, num_lines), self.lats, self.longs, 5280, mode="array" ) - values = rotate( - values, angle=viewpoint_angle, reshape=not crop, order=interpolation - ) - + values = rotate(values, angle=viewpoint_angle, reshape=not crop, order=interpolation) + return values def preprocess( @@ -178,10 +173,7 @@ def preprocess( values = (values - np.min(values)) / (np.max(values) - np.min(values)) is_water = values < np.percentile(values, water_ntile) - is_lake = ( - rank.gradient(img_as_ubyte(values), footprint_rectangle((3, 3))) - < lake_flatness - ) + is_lake = rank.gradient(img_as_ubyte(values), square(3)) < lake_flatness values[nan_vals] = np.nan values[np.logical_or(is_water, is_lake)] = np.nan @@ -201,7 +193,7 @@ def plot_annotation( background=True, ax=None, ): - """Plot an annotation to an existing map. + """Plot an annotation to an existing map It is recommended to call this function only after calling map_plot() @@ -225,26 +217,23 @@ def plot_annotation( If there is a background or not ax : matplotlib Axes You can pass your own axes, but probably best not to - + Returns ------- matplotlib.Axes - """ + """ if ax is None and self.ax is None: - raise ValueError( - "No axes found: Either plot_map() beforehand or pass an matplotlib.Axes value " - "to the function." - ) - if ax is None: + raise ValueError("No axes found: Either plot_map() beforehand or pass an matplotlib.Axes value through") + elif ax is None: ax = self.ax - + highest_zorder = max(text.zorder for text in ax.texts) if ax.texts else 1 - + rel_coordinates = ( (coordinates[0] - self.longs[0]) / (self.longs[1] - self.longs[0]), (coordinates[1] - self.lats[0]) / (self.lats[1] - self.lats[0]), ) - + annotation_color = "black" if color: annotation_color = color @@ -276,10 +265,10 @@ def plot_annotation( ms=annotation_size, zorder=highest_zorder, ) - + self.ax = ax return ax - + # pylint: disable=too-many-arguments,too-many-locals def plot_map( self, @@ -337,6 +326,7 @@ def plot_map( ------- matplotlib.Axes """ + if kind not in {"gradient", "elevation"}: raise TypeError("Argument `kind` must be one of 'gradient' or 'elevation'") if values is None: @@ -393,6 +383,6 @@ def plot_map( for spine in ax.spines.values(): spine.set_visible(False) ax.set_facecolor(background_color) - + self.ax = ax return ax