-
Notifications
You must be signed in to change notification settings - Fork 389
DOC: new example, recreation of The Simpsons Monorail Map #2585
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
base: main
Are you sure you want to change the base?
Changes from all commits
90b834c
0dd1e49
4e08224
be4f927
05f29a5
5ba6950
dfd5542
701ca15
1468b5c
0f018e6
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||
|---|---|---|---|---|
| @@ -0,0 +1,129 @@ | ||||
| """ | ||||
| Recreation of the Monorail Map from The Simpsons | ||||
| ------------------------------------------------ | ||||
|
|
||||
| This example demonstrates how to create a minimal outline map of a | ||||
| defined area of land such as a continent, with optional labels at | ||||
| specified locations within the region, in the form of a recreation of the | ||||
| Monorail Map from The Simpsons with humorously oversized labelling (to | ||||
| imitate handwriting/scribbles) and sparsity of marked locations | ||||
| (which are all fictional). | ||||
|
|
||||
| Specifically, it aims to recreate to best likeness using Cartopy | ||||
| the map of pre-Springfield Lyle Lanley Monorail locations from the | ||||
| iconic episode 'Marge vs. the Monorail' (1993) of the TV Series, as | ||||
| taken in likeness from the screen grab available at: | ||||
| https://simpsons.fandom.com/wiki/Brockway. | ||||
|
|
||||
| """ | ||||
|
|
||||
| import matplotlib.pyplot as plt | ||||
| from matplotlib.transforms import offset_copy | ||||
|
|
||||
| import cartopy.crs as ccrs | ||||
| import cartopy.io.shapereader as shpreader | ||||
| from matplotlib.patches import Rectangle | ||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Unused import |
||||
|
|
||||
|
|
||||
| # Define choices for projection and locations to plot | ||||
| GEOM_PROJ = ccrs.PlateCarree() | ||||
| # Not real places, so locations pulled from location on map in still image | ||||
| # First value 2-tuple is the dot placemap location, second is where to write | ||||
| # the text label relative to that dot, to best match the map from the show. | ||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add a comment that the integer is text rotation? |
||||
| LOCATIONS_TO_PLOT = { | ||||
| "Ogdenville": [(-111.8, 35.5), (1.5, -2.2), -6], | ||||
| "North\nHaverbrook": [(-99.0, 43.5), (2.8, -0.5), -1], | ||||
| "Brockway": [(-80.4, 33.6), (-3.4, -1.5), 3], | ||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I guess the second tuple here is expressed in degrees. If it was expressed in points then Feel free to push back if there is a reason not to do that! |
||||
| } | ||||
|
|
||||
|
|
||||
| def main(): | ||||
| # Set up a plot with a light blue background and a white overall border. | ||||
| # For proportions of land mass, font size and border to be as | ||||
| # intended, need to keep 'figsize' and 'dpi' (4:3 ratio) as below. | ||||
| fig = plt.figure( | ||||
| figsize=(9, 7.5), | ||||
| dpi=125, | ||||
| facecolor="#AFCBBD", | ||||
| edgecolor="white", # sets up white border without need for another axes | ||||
| linewidth=30, # makes the border thicker as per original map | ||||
| ) | ||||
| map_ax = fig.add_axes( | ||||
| [0.035, 0.035, 0.93, 0.93], projection=ccrs.LambertConformal(), frameon=False | ||||
| ) | ||||
|
|
||||
| # Center on location of USA with a bit of space on all sides to pad | ||||
| map_ax.set_extent([-120, -72.5, 20, 50], crs=ccrs.Geodetic()) | ||||
|
|
||||
| # Plot only the USA landmass, in a fawn colour with a thin black border | ||||
| shpfilename = shpreader.natural_earth( | ||||
| resolution="110m", category="cultural", name="admin_0_countries" | ||||
| ) | ||||
| countries = shpreader.Reader(shpfilename).records() | ||||
| usa_border = [ | ||||
| country.geometry | ||||
| for country in countries | ||||
| if (country.attributes["NAME"] == "United States of America") | ||||
| ] | ||||
| map_ax.add_geometries( | ||||
| usa_border, | ||||
| GEOM_PROJ, | ||||
| facecolor="#C39B6A", | ||||
| edgecolor="black", | ||||
| ) | ||||
|
|
||||
| # Now add the location labels one by one | ||||
| for loc_name, loc_details in LOCATIONS_TO_PLOT.items(): | ||||
| loc_coords, rel_text_pos, text_rot = loc_details | ||||
| map_ax.plot( | ||||
| *loc_coords, | ||||
| marker="o", | ||||
| color="black", | ||||
| markersize=6, | ||||
| transform=GEOM_PROJ, | ||||
| ) | ||||
|
|
||||
| # Adjust position of location name text relative to location marker | ||||
| text_loc_coords = ( | ||||
| loc_coords[0] + rel_text_pos[0], | ||||
| loc_coords[1] + rel_text_pos[1], | ||||
| ) | ||||
| # Text in uppercase, very bold handwriting-like font, as per the | ||||
| # screen grab of the map from the show | ||||
| map_ax.annotate( | ||||
| loc_name.upper(), | ||||
| xy=text_loc_coords, | ||||
| transform=ccrs.Geodetic(), | ||||
| xytext=(-25, 0), # shift text closer to point as per reference | ||||
| textcoords="offset pixels", | ||||
| verticalalignment="center", | ||||
| horizontalalignment="left", | ||||
| fontname="Charcoal", # ensure you have this font available | ||||
| fontweight="black", | ||||
| fontsize=28, | ||||
| rotation=text_rot, # slightly wonky text for handwritten effect | ||||
| ) | ||||
|
|
||||
| leg_text = ( | ||||
| "Pre-Springfield Lanley\nMonorail locations in TV's\nThe Simpsons\n" | ||||
| "(recreation of map at\nsimpsons.fandom.com/\nwiki/Brockway)" | ||||
| ) | ||||
|
|
||||
| # Add the bottom left 'compass' legend in spirit of the original map. | ||||
| map_ax.text( | ||||
| 0.14, | ||||
| 0.10, | ||||
| leg_text, | ||||
| transform=map_ax.transAxes, | ||||
| fontsize=11, | ||||
| horizontalalignment="center", | ||||
| verticalalignment="center", | ||||
| style="italic", | ||||
| bbox=dict(facecolor="#A5B5CE"), | ||||
| ) | ||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Optional: could consider using AnchoredText here if you want the legend text right in the corner. |
||||
|
|
||||
| plt.show() | ||||
|
|
||||
|
|
||||
| if __name__ == "__main__": | ||||
| main() | ||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unused import