有没有办法调整使用 Plotly 创建的离散等值线的图例项的大小?
Is there a way to resize the legend items of a discrete choropleth created using Plotly?
我正在使用 Python,如果有帮助的话,尽管我相信任何解决方案都与语言无关。我已经使用 plotly.express 创建了一个离散的 choropleth 地图框,但是当以高分辨率导出时,图例项目(字体和颜色)实际上变得不可读。如果我记得,Plotly 通过叠加多条迹线来创建离散图形,所以不确定我们是否可以在迹线或图形级别做一些事情来修复。
如果有帮助,很高兴分享代码,尽管我实际上还没有更新图例,所以我认为它不会增加任何内容。
Hi-res map output
Std map output
代码:
DISCRETE = 11
def gen_colorscale(obs, color="viridis"):
color = px.colors.sample_colorscale(color, obs)
p1 = tuple(zip(np.linspace(0, 1, obs+1)[:-1], color))
p2 = tuple(zip(np.linspace(0, 1, obs+1)[1:], color))
cs = []
for a, b in zip(p1, p2):
cs.append(a)
cs.append(b)
return cs
cs = gen_colorscale(DISCRETE)
# color range
cr = [0, 10000]
# tick vals
v = np.linspace(*cr, DISCRETE)
vt = (
pd.DataFrame(v, columns=["v"])
.apply(lambda v: (v / 10 ** 3).round(1))
.apply(lambda v: v.astype(str) + "k to " + v.shift(-1).astype(str) + "k")
.values
)
vt[0] = v[0].astype(str) + " to " + (v[1] / 10 ** 3).round(1).astype(str) + "k"
vt[-1] = ">" + (v[-1] / 10 ** 3).round(1).astype(str) + "k"
fig = px.choropleth_mapbox(
df,
geojson=counties,
locations="fips",
color="migration",
range_color=[cr[0], cr[1] + cr[1]/(DISCRETE-1)],
color_continuous_scale=cs,
labels={"migration": "Migration (k)"},
center={"lat": 37.0902, "lon": -95.7129},
zoom=4.2,
opacity=1.0,
mapbox_style="white-bg",
)
fig.update_layout(
mapbox_style="mapbox://styles/ryangilland/ckwqzs8ck0h5f14nybww9c5ts",
mapbox_accesstoken=token,
coloraxis_colorbar=dict(
tickvals=np.linspace(cr[0]+cr[1]/(DISCRETE-1)/2,cr[1] + cr[1]/(DISCRETE-1)/2,DISCRETE),
ticktext=vt,
len=0.8,
thickness=50,
xanchor="right",
x=1.0,
bgcolor="rgba(22,33,49,1)",
tickfont=dict(color="rgba(255,255,255,1)"),
),
margin=dict(l=0, r=0, b=50, t=75, pad=4),
paper_bgcolor="rgba(8,18,23,1)",
plot_bgcolor="rgba(8,18,23,1)",
)
fig.show()
Sample Image
- 以另一种方式看待这个问题。 https://plotly.com/python/colorscales/#constructing-a-discrete-or-discontinuous-color-scale
- 因此您可以使用离散桶来创建色标
- 我希望这在高分辨率屏幕上运行良好,因为彩条使用屏幕的整个高度
- 如果不需要使用tickvals或ticktext解决方案就简单多了
import geopandas as gpd
import numpy as np
import pandas as pd
import plotly.express as px
gdf = gpd.read_file(gpd.datasets.get_path("naturalearth_lowres")).set_index("iso_a3")
DISCRETE = 6
# build discrete continuous colorscale
cs = [
(a, px.colors.sample_colorscale("viridis", b)[0])
for a, b in zip(
np.repeat(np.linspace(0, 1, DISCRETE + 1), 2)[1:-1],
np.repeat(np.linspace(0, 1, DISCRETE + 1), 2),
)
]
# color range
cr = [0, gdf["pop_est"].quantile(.95)]
# tick vals
v = np.linspace(*cr, DISCRETE+1)
vt = (
pd.DataFrame(v, columns=["v"])
.apply(lambda v: (v / 10 ** 6).round(0).astype(int))
.apply(lambda v: v.astype(str) + "M to " + v.shift(-1).astype(str) + "M")
.values
)
px.choropleth_mapbox(
gdf,
geojson=gdf.__geo_interface__,
locations=gdf.index,
color="pop_est",
color_continuous_scale=cs,
range_color=cr,
).update_layout(
mapbox={"style": "carto-positron", "zoom": .5},
coloraxis={"colorbar": {"tickvals": v[1:] - v[1]/2, "ticktext":vt}},
margin={"l":0,"r":0,"t":0,"b":0}
)
我正在使用 Python,如果有帮助的话,尽管我相信任何解决方案都与语言无关。我已经使用 plotly.express 创建了一个离散的 choropleth 地图框,但是当以高分辨率导出时,图例项目(字体和颜色)实际上变得不可读。如果我记得,Plotly 通过叠加多条迹线来创建离散图形,所以不确定我们是否可以在迹线或图形级别做一些事情来修复。
如果有帮助,很高兴分享代码,尽管我实际上还没有更新图例,所以我认为它不会增加任何内容。
Hi-res map output
Std map output
代码:
DISCRETE = 11
def gen_colorscale(obs, color="viridis"):
color = px.colors.sample_colorscale(color, obs)
p1 = tuple(zip(np.linspace(0, 1, obs+1)[:-1], color))
p2 = tuple(zip(np.linspace(0, 1, obs+1)[1:], color))
cs = []
for a, b in zip(p1, p2):
cs.append(a)
cs.append(b)
return cs
cs = gen_colorscale(DISCRETE)
# color range
cr = [0, 10000]
# tick vals
v = np.linspace(*cr, DISCRETE)
vt = (
pd.DataFrame(v, columns=["v"])
.apply(lambda v: (v / 10 ** 3).round(1))
.apply(lambda v: v.astype(str) + "k to " + v.shift(-1).astype(str) + "k")
.values
)
vt[0] = v[0].astype(str) + " to " + (v[1] / 10 ** 3).round(1).astype(str) + "k"
vt[-1] = ">" + (v[-1] / 10 ** 3).round(1).astype(str) + "k"
fig = px.choropleth_mapbox(
df,
geojson=counties,
locations="fips",
color="migration",
range_color=[cr[0], cr[1] + cr[1]/(DISCRETE-1)],
color_continuous_scale=cs,
labels={"migration": "Migration (k)"},
center={"lat": 37.0902, "lon": -95.7129},
zoom=4.2,
opacity=1.0,
mapbox_style="white-bg",
)
fig.update_layout(
mapbox_style="mapbox://styles/ryangilland/ckwqzs8ck0h5f14nybww9c5ts",
mapbox_accesstoken=token,
coloraxis_colorbar=dict(
tickvals=np.linspace(cr[0]+cr[1]/(DISCRETE-1)/2,cr[1] + cr[1]/(DISCRETE-1)/2,DISCRETE),
ticktext=vt,
len=0.8,
thickness=50,
xanchor="right",
x=1.0,
bgcolor="rgba(22,33,49,1)",
tickfont=dict(color="rgba(255,255,255,1)"),
),
margin=dict(l=0, r=0, b=50, t=75, pad=4),
paper_bgcolor="rgba(8,18,23,1)",
plot_bgcolor="rgba(8,18,23,1)",
)
fig.show()
Sample Image
- 以另一种方式看待这个问题。 https://plotly.com/python/colorscales/#constructing-a-discrete-or-discontinuous-color-scale
- 因此您可以使用离散桶来创建色标
- 我希望这在高分辨率屏幕上运行良好,因为彩条使用屏幕的整个高度
- 如果不需要使用tickvals或ticktext解决方案就简单多了
import geopandas as gpd
import numpy as np
import pandas as pd
import plotly.express as px
gdf = gpd.read_file(gpd.datasets.get_path("naturalearth_lowres")).set_index("iso_a3")
DISCRETE = 6
# build discrete continuous colorscale
cs = [
(a, px.colors.sample_colorscale("viridis", b)[0])
for a, b in zip(
np.repeat(np.linspace(0, 1, DISCRETE + 1), 2)[1:-1],
np.repeat(np.linspace(0, 1, DISCRETE + 1), 2),
)
]
# color range
cr = [0, gdf["pop_est"].quantile(.95)]
# tick vals
v = np.linspace(*cr, DISCRETE+1)
vt = (
pd.DataFrame(v, columns=["v"])
.apply(lambda v: (v / 10 ** 6).round(0).astype(int))
.apply(lambda v: v.astype(str) + "M to " + v.shift(-1).astype(str) + "M")
.values
)
px.choropleth_mapbox(
gdf,
geojson=gdf.__geo_interface__,
locations=gdf.index,
color="pop_est",
color_continuous_scale=cs,
range_color=cr,
).update_layout(
mapbox={"style": "carto-positron", "zoom": .5},
coloraxis={"colorbar": {"tickvals": v[1:] - v[1]/2, "ticktext":vt}},
margin={"l":0,"r":0,"t":0,"b":0}
)