0

Suppose I have a file file.tif. I want to plot a scale bar based on its CRS, using Python.

I've tried using a mix of rasterio, matplotlib and other techniques, but I fail because of the scale bar part, where I can't find a method that makes use of its CRS:

import numpy as np
import matplotlib.pyplot as plt
import rasterio as rio

raster = rio.open('./file.tif')
data = raster.read()

plt.imshow(data)
plt.colorbar(label='clusters', fraction=0.02)
# generating the scale bar should go here and take advantage of the `raster.crs` attribute
plt.plot()

raster plot without a scale bar

1
  • 1
    Welcome to GIS SE. Please edit your question to include a single, focused question and any code that you have attempted along with any pertinent errors.
    – Aaron
    Jun 10, 2023 at 3:44

1 Answer 1

1

The easiest way is to use matplotlib-scalebar

pip install matplotlib-scalebar

The key to getting the scale right is to use rasterio.plot.plotting_extent to set the extent that you then pass to pyplot.imshow.

Then you can do something like:

import matplotlib.pyplot as plt
from matplotlib_scalebar.scalebar import ScaleBar

import rasterio
from rasterio.plot import plotting_extent

fig, ax = plt.subplots(1, figsize=(6, 6))

with rasterio.open("https://github.com/rasterio/rasterio/raw/main/tests/data/float.tif") as raster:
    extent = plotting_extent(raster)
    data = raster.read(1)
    plt.imshow(data, extent=extent)
    scalebar = ScaleBar(1, location="lower left")
    plt.colorbar(label='clusters', fraction=0.02, ax=ax)
    ax.add_artist(scalebar)

plt.show()

enter image description here

Another example of output of above code that uses "https://github.com/rasterio/rasterio/raw/main/tests/data/RGB.byte.tif":

enter image description here

For simpler use cases where you don't need a legend, i.e if you are plotting RGB imagery, you don't need to set the extent, just use rasterio.plot.show which will set it correctly for you:

import matplotlib.pyplot as plt
from matplotlib_scalebar.scalebar import ScaleBar

import rasterio
from rasterio.plot import show

fig, ax = plt.subplots(1, figsize=(6, 6))

with rasterio.open("https://github.com/rasterio/rasterio/raw/main/tests/data/RGB.byte.tif") as raster:
    show(raster, ax=ax)
    scalebar = ScaleBar(1, location="lower left")
    ax.add_artist(scalebar)

plt.show()

enter image description here

2
  • Wow, this exactly what I needed! Many thanks. I need one clarification on your last example: I don't need to set the extent explicitly because rasterio already calls the plotting_extent function during show? Or it does so in another way? Jun 11, 2023 at 1:39
  • Correct, see edit.
    – user2856
    Jun 11, 2023 at 1:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.