有没有办法调整使用 Plotly 创建的离散 choropleth 的图例项的大小?
Posted
技术标签:
【中文标题】有没有办法调整使用 Plotly 创建的离散 choropleth 的图例项的大小?【英文标题】:Is there a way to resize the legend items of a discrete choropleth created using Plotly? 【发布时间】:2022-01-07 09:47:35 【问题描述】:如果有帮助,我正在使用 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
【问题讨论】:
【参考方案1】: 以另一种方式看待这个问题。 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
)
【讨论】:
这很有帮助!只是在此基础上构建,因为这在某种程度上是一种伪装的连续比例,是否有一个颜色范围是单点的?例如,如果我只想为等于 0 的条目设置一种颜色,然后为 >0 和 130.0M”桶。我将当前代码添加到原始代码中,这有助于生成我添加的图像(阿拉斯加和夏威夷分别添加并粘贴到我的脚本中),以上是关于有没有办法调整使用 Plotly 创建的离散 choropleth 的图例项的大小?的主要内容,如果未能解决你的问题,请参考以下文章
如何让 Plotly 根据 Streamlit 应用程序中的屏幕分辨率调整绘图大小?
有没有办法用 plotly 或 python 创建条形图可视化,其中 y 轴是 24 小时范围,x 轴是所有工作日?