-
Notifications
You must be signed in to change notification settings - Fork 29
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
Matplotlib-Scalebar does not fully supports geopandas geodataframe plots #20
Comments
I got a work around - the meter_per_px is off by a factor of figure's dpi/2. So I added the lines
It's not perfect, all I needed was to convey a sense of scale to the reader. |
Dear Seangrogan, thank you for your reply. What I am still wondering is the matter of the figure dpi. Assuming that the fig dpi is altered posteriori to the scalebar insertion, wouldn't it suffer from it? In another words, if the figure dpi is altered, would the scalebar precision be also altered? If that is the case, I believe that a fig.transfigure (transform) would be more formal for scalebar construction. I thank you for your time, and I hope hearing from you soon. Sincerely yours, Philipe Leal |
No idea, not the author. Only had a similar problem. As soon as I realized the change when changing the DPI changed the scale bar (and had some free time to look again) - it was easy to uncover the workaround. I also realized in digging into the source code and other issues it really seems to be intended for use with calibrated pictures (MRI scans, microscope images, etc), not scatterplots. I just needed a quick-and-dirty way to show a sense of scale in a scatterplot, not a (which, in my project, isn't pictures of states but rather city blocks).
It didn't seem to bother it. I changed the dpi to 1000 and then changed it back to 100 before saving the plot. It seems to maintain the scale appropriately. Which makes sense as the code immediately applies the scale-bar to the plot (so anything you do to the plot . There might be a problem if you change the dpi between creating the scale bar and and adding the scale bar, i.e.
1000 back to 100 after adding scale bar. Speculation: I think it's in how the prefered units are calculated, because the |
Thank you for submitting this issue. @seangrogan is absolutely right, the library was design for calibrated images. In other words, the scale bar follows the values/units of the x-axis. I am unfamiliar with geopandas, but from what I can see in the package's documentation, the x-axis corresponds to longitudes and not distances, e.g. I think this is the cause of this issue. Do you know if there is a way to plot the maps differently where the axis would use distances? |
Converting WGS (lat/lon) to UTM (eastings/northings) could work. UTM's coordinates are explicitly in meters, so something that is at (10, 10) and something else that is at (16, 18) is 10 meters apart. Plotting in WGS - following the formula from my original reply [1] I get an initial meters-per-px of 176 and adjusting using [2] I get 88154. Plotting in UTM, I get 172 (similar order)[1], but the scale comes in on the order of Mm So... with a little experimentation - i found the adjustment needed was
and get the 'adjusted value' of 1.03.... for context, the extent of the UTM image in the x axis is [102_609, 957_664] and y is [3_709_784, 4_122_437] (and these units are meters) [1]
[2]
Note: I use the following to convert lat-lon to UTM: https://github.com/Turbo87/utm/ keep in mind that a UTM coordinate has a cardinality of 4, not 2 i.e. (EASTING, NORTHING, ZONE NUMBER, ZONE LETTER) Edit: I probably should label the axis for clarity. |
I think if the extent of the axes are in meters, you should just need to set
Could you try with another example to check if my logic works? If it works, I can add a note in the README for other users of geopandas. |
Ahhhhh! It's not so much it isn't clear as it didn't really occur to me (or seem relevant) as I wasn't using an image (CT scan, whatever). Probably because I've actually never used MatPlotLib in this manner - I didn't quite understand it. Using UTM coordinates, it does indeed still plot accurately as 150KM With this newfound understanding, for WGS (Lat/Lon) I used this modified code:
It plots a scalebar at about 35.3 North like so: Distance will vary based on Latitude (hence the _y = (y1+y2)/2). It might be hard to see in the following picture, but the top scale bar is (about) 850 px across and the bottom is 893 px across (Using gimp to measure it) Theoretically, you could use any two points on the same latitude that are one degree apart in longitude (y), e.g.:(-0.5, 35.3) and (0.5, 35.3) Also, because math is hard, I never realized that
If you don't mind a proposal for this : If you're attempting to plot data that are geospatial coordinates (such as using scatterplots to plot the location of structures): if you're using a coordinate system based on UTM where the X and Y are in meters, simply set Edit : Also.... Thanks for your help Philippe @ppinard and engaging with us to find a solution. I really appreciate it! |
Dear all,
thank you for your reply.
This later answer was precisely what I needed.
Sincerely yours,
Philipe Riskalla Leal,
Sensoriamento Remoto - INPE
Limnologia - USP
Em seg, 15 de jul de 2019 às 13:11, Sean Grogan <notifications@github.com>
escreveu:
… It is mentioned in the README, but perhaps it is not very clear:
Set dx to 1.0 if the axes image has already been calibrated by setting its
extent.
Ahhhhh! It's not so much it isn't clear as it didn't really occur to me
(or seem relevant) as I wasn't using an image (CT scan, whatever). Probably
because I've actually never used MatPlotLib in this manner - I didn't quite
understand it.
Using UTM coordinates, it does indeed still plot accurately as 150KM
[image: StationsUTM]
<https://user-images.githubusercontent.com/7748811/61226911-51ba3e00-a6f1-11e9-8d85-88e3416c0638.png>
With this newfound understanding, for WGS (Lat/Lon) I used this modified
code:
x1, x2, y1, y2 = ax.axis()
_y = (y1+y2)/2
p1, p2 = (int(x1), _y), (int(x1)+1, _y)
meter_per_deg = great_circle_calculator.distance_between_points(p1, p2)
scale_bar = ScaleBar(meter_per_deg, units="m", location=kwargs.get("location", "lower left"),
fixed_value=kwargs.get("fixed_value", None), fixed_units=kwargs.get("fixed_units", None))
fig.gca().add_artist(scale_bar)
It plots a scalebar at about 35.3 North like so:
[image: stations]
<https://user-images.githubusercontent.com/7748811/61228587-8c71a580-a6f4-11e9-9400-68f8fba2c10b.png>
Distance will vary based on Latitude (hence the _y = (y1+y2)/2). It might
be hard to see in the following picture, but the top scale bar is (about)
850 px across and the bottom is 893 px across (Using gimp to measure it)
[image: stations - two scale bars]
<https://user-images.githubusercontent.com/7748811/61229546-60efba80-a6f6-11e9-8b1f-7224f8d74e41.png>
Theoretically, you could use any two points on the same latitude that are
one degree apart in longitude (y), e.g.:(-0.5, 35.3) and (0.5, 35.3)
------------------------------
Also, because math is hard, I never realized that meter_per_px_adjusted
was both multiplied by and divided by fig.dpi. Doh moment.
------------------------------
Could you try with another example to check if my logic works? If it
works, I can add a note in the README for other users of geopandas.
If you don't mind a proposal for this :
If you're attempting to plot data that are geospatial coordinates (such as
using scatterplots to plot the location of structures): if you're using a
coordinate system based on UTM where the X and Y are in meters, simply set
dx=1. If you are plotting geospatial coordinates based on WGS where X and
Y are in latitude (Y) and longitude (X), you will need to compute the
distance between two points at the latitude (Y) you wish to have the scale
represent that are also one full degree of longitude (X) apart, in meters.
For example dx = great_circle_distance((X, Y), (X+1, Y))
—
You are receiving this because you authored the thread.
Reply to this email directly, view it on GitHub
<#20?email_source=notifications&email_token=AHYJVOWHJUJIKWYPSPW5SX3P7SOSHA5CNFSM4HQMKJUKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODZ6F2KA#issuecomment-511466792>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AHYJVOW2DQ4ZOQAYYRLUHILP7SOSHANCNFSM4HQMKJUA>
.
|
Dear all,
I have recently tried the matplotlib-scalebar module over some geopandas geodataframe plot. I noticed that the the given module does not well support the plot. This is due to the "dx" argument. Since the geopandas plot does not have a size of pixel, the "dx" setting is akward, and prone to errors.
Sincerely yours,
Philipe Leal
The text was updated successfully, but these errors were encountered: