Skip to content

Conversation

@sadielbartholomew
Copy link
Contributor

@sadielbartholomew sadielbartholomew commented Oct 23, 2025

Rationale

For fun (and love of said TV Series), I have recreated the Monorail Map from The Simpsons using Cartopy - the challenge was to get as close to likeness as I could using the standard Python visualisation ecosystem - matplotlib etc, in a small-ish script, and Cartopy made this simple.

Whist I did this mostly with the motivation of making high-res print outs for myself, I think it would make a good example for your examples gallery. As I summarise in the top-level docstring:

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,

Moreover, other vis libraries with examples galleries have humorous examples - notably the XKCD examples - so I think i is nice to add (another) one to the Cartopy examples gallery.

From other PRs adding new examples I have found from a quick search, it seems that I just need to add the new script in the appropriate place under 'cartopy/examples/` and the relevant subdirectory to categorise - I think 'miscellanea' is most suitable, but happy to move it if you wish.

Please let me know if you would like me to adjust it in any way if you would accept it for the gallery - either codewise or output-wise.

Implications

A new example recipe will be added to the docs and maybe somebody will find it useful and/or amusing. 🙂

Notes

The output (with Python 3.12) is:

Original from when PR opened:

504936792-10f33258-e212-484b-9eb1-57b190c940e0

Updated output after feedback response and tweaks, at a8baf8a:

new_simpsons_map

For reference, the original looks like this.

@CLAassistant
Copy link

CLAassistant commented Oct 23, 2025

CLA assistant check
All committers have signed the CLA.

@sadielbartholomew sadielbartholomew changed the title DOC: new misc. example, recreation of The Simpsons Monorail Map DOC: new example, recreation of The Simpsons Monorail Map Oct 23, 2025
@sadielbartholomew
Copy link
Contributor Author

Hi @greglucas, thanks for your helpful review. I committed one one-line trivial suggestion and addressed the other comments in a few new commits, so this is now ready for re-review.

For context, to clarify relating to the feedback and my response in those commits:

  • I now recall the reason that there were two axes objects in the original PR script (I wrote the code a good year or so ago and only now have I got around to making this PR, so forgot this but also didn't make it clear via variable naming or comments so my bad!) which was to create the white border around the main map area (everything plotted with the light blue background etc.). However, I realised now that this can be done using an edge set on the entire figure, avoiding the need for the confusing double-axes situation, so I have changed the code up to set that and have one axis now. Overall it makes the example much cleaner and concise.

@rcomer
Copy link
Member

rcomer commented Nov 3, 2025

@sadielbartholomew the unrelated doc failure is now fixed on main. So if you rebase, the ReadTheDocs CI should go green 🤞

)

# Now add the location labels. The general approach is that covered in
# the 'Map tile acquisition' Catopy example, including the comment below.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think annotate is the right tool for this job these days, so I have opened #2596 to update the existing example.

Note, you could use 'offset points' or 'offset fontsize' if you prefer one of those to 'offset pixels'.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, so what should I do for my PR code, if anything?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I recommend using annotate, as it should simplify the code (and not make use of the private _as_mpl_transform method).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I see now. I used the PR you referenced as a guide on what to do and updated this in 1468b5c. That part of the logic indeed looks much cleaner and simpler now, thanks!

This point should now be resolved but I'll leave you to mark it as such.

@sadielbartholomew sadielbartholomew force-pushed the example-monorail-map-recreation branch from a8baf8a to 701ca15 Compare November 4, 2025 15:25
@sadielbartholomew
Copy link
Contributor Author

Have addressed new feedback from @rcomer (awaiting one clarification RE #2585 (comment)) and force pushed after rebasing onto main.

@sadielbartholomew
Copy link
Contributor Author

Sorry I missed @rcomer's new comment a few weeks ago, but I have now addressed that point - see comment on the thread above. As far as I am concerned, all feedback has been addressed so this is ready to merge (else ready for another round of review). Thanks.

"""

import matplotlib.pyplot as plt
from matplotlib.transforms import offset_copy
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
from matplotlib.transforms import offset_copy

Unused import


import cartopy.crs as ccrs
import cartopy.io.shapereader as shpreader
from matplotlib.patches import Rectangle
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
from matplotlib.patches import Rectangle

Unused import

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.
Copy link
Member

Choose a reason for hiding this comment

The 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],
Copy link
Member

Choose a reason for hiding this comment

The 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 annotate could take xy=loc_coords, xytext=rel_text_pos.

Feel free to push back if there is a reason not to do that!

verticalalignment="center",
style="italic",
bbox=dict(facecolor="#A5B5CE"),
)
Copy link
Member

Choose a reason for hiding this comment

The 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants