-
Notifications
You must be signed in to change notification settings - Fork 18
Description
Hi,
I've recently been making maps using the new(ish) matplotlib-map-utils package, referenced in the new geopandas documentation.
There appear to be some compatibility issues somewhere with ultraplot.
If I run this simple code:
from matplotlib_map_utils.core.scale_bar import ScaleBar, scale_bar
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
bounds = [-122.3094136, 41.02776967, -121.65305008, 41.61986174]
c_lon = (bounds[0] + bounds[2]) / 2
c_lat = (bounds[1] + bounds[3]) / 2
plot_crs = ccrs.LambertConformal(central_longitude=c_lon, central_latitude=c_lat)
fig, ax = plt.subplots(subplot_kw={'projection': plot_crs}, dpi=150)
ax.set_extent((bounds[0], bounds[2], bounds[1], bounds[3]), crs=ccrs.PlateCarree())
scale_bar(ax, bar={"projection": plot_crs})
fig.savefig('test.png', dpi=150)
The code runs and the figure saves just fine.
However, if I do this with ultraplot instead..
from matplotlib_map_utils.core.scale_bar import ScaleBar, scale_bar
import matplotlib.pyplot as plt
import cartopy.crs as ccrs
bounds = [-122.3094136, 41.02776967, -121.65305008, 41.61986174]
c_lon = (bounds[0] + bounds[2]) / 2
c_lat = (bounds[1] + bounds[3]) / 2
plot_crs = ccrs.LambertConformal(central_longitude=c_lon, central_latitude=c_lat)
fig, ax = uplt.subplots(projection=plot_crs, dpi=150)
ax.set_extent((bounds[0], bounds[2], bounds[1], bounds[3]), crs=ccrs.PlateCarree())
scale_bar(ax, bar={"projection": plot_crs})
fig.savefig('C:/Users/kchudler/Downloads/ultraplot_test.png', dpi=150)
The numbers and text around the scale bar appear fuzzy in the saved image.

Interestingly, if I then rove the first version of the code with mpl again, I get the fuzzy text in the re-saved figure. So it appears as if importing/making a figure with ultraplot monkeys around this the matplotlib settings in a way that impacts future calls to scale_bar
I brought this issue up in the matplotlib-map-utils repo, and this was the response:
Hmmm, I don't mind making changes to this package to work better with
ultraplot, but given that this works fine with classicmatplotlib, I would imagine this is an issue you should raise withultraplot, to at least ask what is going on in their translation step betweenultraplotandmplthat would cause this issue?Interestingly, this seems specific to the
ScaleBarobject - theNorthArrowtext renders fine! That points to a rather specific cause: whileNorthArrows are kept as collections of (vector)artistobjects, the compositeScaleBars (meaning text + the bar itself) are rasterized as images and then placed via anOffsetImageinstead; I had to do things this way to handle some issues with rotation.I don't know why Ultraplot would just be affecting the text though, and not pixelating the rest of the bar - or perhaps it is and we just can't tell?
Unfortunately, I don't really have a lot of time to dive into this myself right now (this is something I work on when I'm between jobs). If you wanted to fork a branch and start debugging yourself, you would probably only have to work in a single file:
scale_bar.pyincore/. You could follow the flow of thescale_bar()function within it, paying particular attention to_temp_figure()and_make_text()and_render_as_image()within it (mainly the first and last), and seeing what the intermediate outputs look like.(I do know that
_temp_figure()creates some newsubplotsusing themplcall so I wonder if that is the issue - perhaps that would be a worthwhile question to ask theultraplotteam.)Let me know your thoughts!