One idea is to overlay a few sacrificial plots and build the legend line-by-line:
using Plots
gr()
rows = Matrix([
"s" "tokyo" 8918018
"s" "delhi" 2605537
"b" "shanghai" 705818
"a" "sao paulo" 580568
"a" "mexico city" 379802
"s" "cairo" 343985
"b" "mumbai" 279183
"b" "beijing" 168452
"b" "dhaka" 123337
"b" "osaka" 117008
])
shapeDict = Dict("s" => :star, "u" => :diamond, "a" => :circle, "b" => :hexagon);
shapes = [shapeDict[src] for src in rows[:, 1]];
custommarkerplot = scatter(rows[:, 2], rows[:, 3],
xticks = :all,
rotation=30,
markersize = 10,
size=(600, 400),
title = "Count per city",
markershape = shapes,
label="",
color=:blue
)
scatter!(1,1, markershape=:star, color=:blue, label="the star series")
scatter!(1,1, markershape=:hexagon, color=:blue, label="the hexagon series")
scatter!(1,1, markershape=:circle, color=:blue, label="the circle series")
savefig(custommarkerplot, "custommarkerplot.png")
