I'm using geodataframe to plot a map of North Amer...
# datascience
c
I'm using geodataframe to plot a map of North America the geojson does have state and province names. I would like to display the names of the states on the map. How do I do that with geoMap or geoPolygon? I have tried inside and outside of geoMap:
Copy code
geoMap {
    text {
        label(stateProvinceName)
        alpha = 1.0
        x(centerX)
        y(centerY)
        font.color = Color.BLACK
        font.size = 12.0
        font.family = FontFamily.SANS
    }
}
The map areas are different colours but black should be very visible. I also tried a range of sizes from 0.1 to 16.0
stateProvinceName
is a column accessor and the relevant column does show up in save html or json but no label is rendered.
a
Hi! Thanks for the report. Right now there is a bug in kandy-geo that causes incorrect behavior of layers when the number of objects in the layer matches the number of features in the geo dataset: https://github.com/Kotlin/kandy/issues/479 As a workaround, you need to manually override the dataset. However, there is another related bug that prevents this if you used
.plot {}
directly on a `GeoDataFrame`: https://github.com/Kotlin/kandy/issues/480 😅 The best current solution is this: 1) Create a regular
DataFrame
with names and centroids, and call
.plot
on it. 2) Add
geoMap
inside the
withData
on the geo dataset.
Copy code
val dfNames = dataFrameOf(
    usaStates.df.name,
    usaStates.df.geometry.map { it.centroid.x } named "nameX",
    usaStates.df.geometry.map { it.centroid.y } named "nameY"
)
and
Copy code
dfNames.plot {
    withData(usaStates) {
        geoMap()
    }
    text {
        label(name)
        x(nameX)
        y(nameY)
    }
}
This should work! Sorry for the inconvenience - kandy-geo is still experimental, and such bugs will be fixed soon!
✅ 1
c
I ran into a new problem. The maps from from geojson found at The maps comes from https://geodata.ucdavis.edu/gadm/gadm4.1 I combined multiple countries and want to provide a different fill color for each country. I even added the countryCode from data set to dfNames.
Copy code
val centerX by column<Double>("center_x")
		val centerY by column<Double>("center_y")
		val countryCode by column<String>("GID_0")
		val stateProvinceName by column<String>("NAME_1")
		val dfNames = dataFrameOf(
			allMaps.df[countryCode] named countryCode.name(),
			allMaps.df[stateProvinceName] named stateProvinceName.name(),
			allMaps.df.geometry.map { it.centroid.x } named centerX.name(),
			allMaps.df.geometry.map { it.centroid.y } named centerY.name()
		)
		logger.info { "dfNames:\n$dfNames" }
		val mapPlot = dfNames.plot {
			withData(allMaps) {
				geoMap {
					fillColor(countryCode) {
						legend.name = "Country Code"
						scale = categorical(
							"USA" to Color.BLUE,
							"CAN" to Color.RED,
							"MEX" to Color.GREEN
						)
					}
					borderLine.color = Color.BLACK
					borderLine.width = 0.1
				}
			}
                        text {
				label(stateProvinceName)
				alpha = 1.0
				x(centerX)
				y(centerY)
				font.color = Color.BLACK
				font.size = 1.0
				font.family = FontFamily.SANS
			}
                        layout {
				title = "Averages by Plant"
				size = plotSize
				style(Style.Grey)
			}
		}
Logs contains:
Copy code
dfNames:
    GID_0        NAME_1    center_x  center_y
  0   USA       Alabama  -86.822436 32.795894
  1   USA       Georgia  -83.458063 32.669567
  2   USA         Idaho -114.664236 44.392208
  3   USA      Illinois  -89.148369 40.131613
  4   USA       Indiana  -86.289025 39.906926
  5   USA          Iowa  -93.495360 42.085584
  6   USA        Kansas  -98.386951 38.461349
  7   USA      Kentucky  -85.262283 37.529804

java.lang.RuntimeException: Variable not found: 'GID_0'. Variables in data frame: ['center_y', 'NAME_1', 'center_x']
it seems the references to column in geoMap or geoPoint inside a dataset is not handled properly unless the outer df is a geodataframe.
a
Oh, ok that's a Lets-Plot problem. Now you can wrap both layers into
withData
:
Copy code
plot {
   withData(dfNames) {
      text {}
   }
   withData(allMaps) {
      geoMap {}
   }
}
That should work.
Will try to fix it on Kandy side: https://github.com/Kotlin/kandy/issues/495