bir*_*rah 5 python data-visualization networkx bokeh
我有以下代码来从NetworkX制作散景图
p = figure(x_range=(-1.1, 1.1), y_range=(-1.1, 1.1))
p.grid.visible = False
p.axis.visible = False
graph_renderer = from_networkx(G, nx.spring_layout, random_state=11, center=(0, 0), scale=1, k=0.5)
color_map = factor_cmap('domain_cat', factors=factors, palette=Category10_6)
graph_renderer.node_renderer.glyph = Circle(radius=0.02, fill_color=color_map, line_color=None, fill_alpha=1)
graph_renderer.edge_renderer.glyph = MultiLine(line_color='lightgray', line_alpha=0.3, line_width=2)
p.renderers.append(graph_renderer)
p.add_tools(HoverTool(tooltips='@index', show_arrow=None))
show(p)
Run Code Online (Sandbox Code Playgroud)
效果很好。但是,我为节点有一个分类颜色图。我想添加一个图例。
使用绘图界面时,只需输入源列名称(https://docs.bokeh.org/en/latest/docs/user_guide/categorical.html#colors),即可轻松添加分类图例。
但是,即使通过模型接口,我也无法使用分类图例Legend和LegendItem来生成方法。
我尝试了以下形式:
items = [LegendItem(label=factor, renderers=[graph_renderer.node_renderer]) for factor in factors]
legend = Legend(items=items)
p.add_layout(legend)
Run Code Online (Sandbox Code Playgroud)
但这会产生以下结果,其中的空白图例表示正确的高度,而控制台错误为TypeError: v is undefined; can't access its "draw_legend" property。
小智 0
我遇到了同样的问题,花了几个小时研究不同的解决方案,但没有像您那样使用 graph_renderer 找到特定的方法。不管怎样,我想出了一个手动解决方案,使用散景Div:
from bokeh.io import show\nfrom bokeh.models import Div\n\nlegendEntries = {\'#1f77b4\': \'192.168.0.0/24\',\n \'#aec7e8\': \'192.168.1.128/25\',\n \'#ff7f0e\': \'192.168.0.0/23\',\n \'#ffbb78\': \'192.168.4.0/25\',\n \'#2ca02c\': \'192.168.5.0/25\'}\n\nwith open ("resources/legend.css", "r") as f:\n legend_css=f.read()\n\nwith open ("resources/legend.html", "r") as f:\n legend_html=f.read()\n\ndef str_legend():\n return "<p>" + "</p><p>".join([f"<span class=\'legend-entry\' style=\'background:{n}\'> </span>{v}" for n, v in legendEntries.items()]) + "</p>"\n\ndiv_legend = Div(css_classes=["legend-container"],\n text=f"<style>{legend_css}</style>{legend_html.replace(\'<p></p>\',str_legend())}")\n\nshow(div_legend)\nRun Code Online (Sandbox Code Playgroud)\n这个脚本main.py至少绘制了一个非交互式图例。
注意 1,然后您需要能够从您的数据创建 legendEntries 字典,但这不应该是一个问题,并且是另一个故事......
\n注意 2,将 html 和 css 文件放在 python 脚本之外会更方便,因为您的编辑器能够根据语法规则突出显示;)
\n为了方便起见,这里是“项目”结构:
\nproject\n\xe2\x94\x82 main.py \n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80\xe2\x94\x80resources\n\xe2\x94\x82 \xe2\x94\x82 legend.css\n\xe2\x94\x82 \xe2\x94\x82 legend.html\nRun Code Online (Sandbox Code Playgroud)\n以及资源文件 legend.html:
\n<fieldset id="legend-1">\n <legend><h4>Legende</h4></legend>\n <p></p>\n</fieldset>\nRun Code Online (Sandbox Code Playgroud)\n和图例.css:
\n.legend-container {\n z-index: 2;\n top: 80px !important;\n left: 780px !important;\n}\n\n.legend-container h4, p {\n margin: 0 0 2px 0;\n}\n\nspan.legend-entry {\n border: solid 0.5px black;\n border-radius: 0.8em;\n -moz-border-radius: 0.8em;\n -webkit-border-radius: 0.8em;\n display: inline-block;\n font-weight: bold;\n line-height: 1.6em;\n margin-right: 7px;\n text-align: center;\n width: 1.6em;\n}\n\n.legend-container fieldset {\n min-width: 140px;\n background: white;\n}\nRun Code Online (Sandbox Code Playgroud)\n要获得这个图例:
\n\n注3:我使用的css样式.legend-container在图中移动图例
| 归档时间: |
|
| 查看次数: |
257 次 |
| 最近记录: |