🎨 Python Echarts Plotting Library
This report summarizes scanner evidence for pyecharts/pyecharts, a Python project with 15,776 GitHub stars. SynthScan examined 35,527 lines of code across 162 source files, recording 504 pattern matches distributed across 9 syntactic categories. The legacy adjusted pattern signal is 12.8 (Moderate pattern signal); it is not an authorship estimate.
Use the findings to ask whether maintainers can explain intent, verify dependencies, simplify unnecessary scaffolding, and focus review effort. Risk Payload v1 adds ownership, supply-chain, over-engineering, and review-effort vectors when available. These are prompts for human verification, not probabilities, security findings, or measured maintenance costs.
Use each vector to guide manual verification of the underlying findings.
Can maintainers explain intent, assumptions, and trade-offs? 276 finding(s).
Are imports declared and package/API names verified? 220 finding(s).
Are wrappers, guards, and repeated structures necessary? 270 finding(s).
Which changes need focused human review? 504 finding(s).
This chart tracks the legacy adjusted pattern score across scan runs. Changes can reflect source changes, scan coverage, or detector/scoring versions; they do not measure AI adoption or prove that a team refactored code. Compare runs only when their scoring versions are compatible. The dashed line tracks the raw pattern-hit count.
Groups findings by configured severity weight. Severity is not a confidence estimate, security rating, or proof that a package is missing. Verify imports against the project's manifests and inspect each finding in its local design context.
This horizontal bar chart shows where configured pattern scores accumulate across directories. Treat the bars as locations to inspect, not as evidence of authorship or code quality. Use the file-level findings to decide whether a directory needs a focused ownership, dependency, complexity, or review check.
The scanner identified 504 distinct pattern matches across 9 syntactic categories. Each entry below represents a discrete location in the source code where the engine recorded a detector match to inspect in context. Expand any category row to inspect the individual file paths, line numbers, code snippets, and the lexical context (CODE, COMMENT, or STRING) in which each match was detected.
Reading the findings table: The Severity column indicates the configured finding weight (CRITICAL / HIGH / MEDIUM / LOW). The Context column identifies whether the match occurred inside executable code, an inline comment, or a string literal — legacy comment-context matches receive a ×1.5 score weight. The ⚡ bolt icon marks clustered matches: three or more patterns within a 10-line window, each receiving an additional ×1.5 density multiplier under the legacy scoring model.
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | AGENTS.md | 199 | def test_chart_line_style_opts(self): | CODE |
| LOW | pyecharts/commons/utils.py | 56 | def replace_placeholder_with_quotes(html: str) -> str: | CODE |
| LOW | pyecharts/commons/utils.py | 109 | def remove_key_with_none_value(incoming_dict): | CODE |
| LOW | pyecharts/charts/basic_charts/wordcloud.py | 43 | def _create_mask_image_variable(self, data: str) -> JsCode: | CODE |
| LOW | test/test_amap.py | 35 | def test_amap_map_control_panel(self, fake_writer): | CODE |
| LOW | test/test_amap.py | 56 | def test_amap_polyline_and_large(self, fake_writer): | CODE |
| LOW | test/test_series_options.py | 21 | def test_label_options_defaults(self): | CODE |
| LOW | test/test_series_options.py | 63 | def test_label_options_custom(self): | CODE |
| LOW⚡ | test/test_series_options.py | 116 | def test_mark_point_item_remove_none(self): | CODE |
| LOW⚡ | test/test_series_options.py | 121 | def test_mark_line_item_remove_none(self): | CODE |
| LOW⚡ | test/test_series_options.py | 126 | def test_mark_area_item_remove_none(self): | CODE |
| LOW | test/test_series_options.py | 149 | def test_mark_area_options_remove_none(self): | CODE |
| LOW | test/test_series_options.py | 158 | def test_tree_map_breadcrumb_options_remove_none(self): | CODE |
| LOW⚡ | test/test_series_options.py | 173 | def test_minor_tick_options_remove_none(self): | CODE |
| LOW⚡ | test/test_series_options.py | 182 | def test_minor_split_line_options_remove_none(self): | CODE |
| LOW⚡ | test/test_series_options.py | 191 | def test_area_color_in_item_styles(self): | CODE |
| LOW⚡ | test/test_series_options.py | 195 | def test_mark_point_opts_with_animation(self): | CODE |
| LOW⚡ | test/test_series_options.py | 199 | def test_mark_line_opts_with_animation(self): | CODE |
| LOW⚡ | test/test_series_options.py | 203 | def test_mark_area_opts_with_animation(self): | CODE |
| LOW | test/test_engine.py | 51 | def test_import_iterable_new_location(self): | CODE |
| LOW | test/test_engine.py | 61 | def test_import_iterable_old_location(self): | CODE |
| LOW | test/test_utils.py | 8 | def test_utils_produce_require_dict(self): | CODE |
| LOW | test/test_utils.py | 37 | def test_utils_produce_require_dict_with_extra(self): | CODE |
| LOW | test/test_utils.py | 58 | def test_utils_remove_key_with_none_value(self): | CODE |
| LOW | test/test_utils.py | 67 | def test_utils_remove_key_with_none_value_raise_value_error(self): | CODE |
| LOW | test/test_effectscatter.py | 19 | def test_effectscatter_item_base(self, fake_writer): | CODE |
| LOW | test/test_grid.py | 11 | def _verify_instance_for_datazoom_and_visualmap(self, chart, key): | CODE |
| LOW | test/test_grid.py | 62 | def _chart_for_set_grid_index(self, gird_index=None) -> Bar: | CODE |
| LOW | test/test_grid.py | 74 | def _chart_for_grid_with_datazoom_and_visualmap(self) -> Bar: | CODE |
| LOW | test/test_grid.py | 95 | def _chart_for_grid_with_multiple_datazoom_and_visualmap(self) -> Bar: | CODE |
| LOW | test/test_grid.py | 143 | def test_grid_set_grid_index_priority(self): | CODE |
| LOW | test/test_grid.py | 170 | def test_grid_set_grid_out_of_order(self): | CODE |
| LOW | test/test_grid.py | 184 | def test_grid_control_axis_index(self): | CODE |
| LOW | test/test_grid.py | 195 | def test_grid_do_not_control_axis_index(self): | CODE |
| LOW | test/test_grid.py | 202 | def test_grid_with_more_datazoom_and_visualmap_opts(self): | CODE |
| LOW | test/test_tree.py | 38 | def test_tree_collapse_interval(self, fake_writer): | CODE |
| LOW | test/test_gmap.py | 35 | def test_gmap_map_control_panel(self, fake_writer): | CODE |
| LOW | test/test_gmap.py | 52 | def test_gmap_polyline_and_large(self, fake_writer): | CODE |
| LOW | test/test_chart_options.py | 30 | def test_bar_background_style_options_remove_none(self): | CODE |
| LOW | test/test_chart_options.py | 43 | def test_globe_layers_options_remove_none(self): | CODE |
| LOW⚡ | test/test_chart_options.py | 54 | def test_theme_river_item_remove_none(self): | CODE |
| LOW⚡ | test/test_chart_options.py | 59 | def test_tree_river_item_remove_none(self): | CODE |
| LOW⚡ | test/test_chart_options.py | 64 | def test_timeline_check_pointer_style_options_remove_none(self): | CODE |
| LOW | test/test_chart_options.py | 80 | def test_timeline_control_style_options_remove_none(self): | CODE |
| LOW⚡ | test/test_chart_options.py | 96 | def test_graph_category_item_remove_none(self): | CODE |
| LOW⚡ | test/test_chart_options.py | 101 | def test_tree_map_item_style_options_remove_none(self): | CODE |
| LOW⚡ | test/test_chart_options.py | 109 | def test_graphic_image_style_opts_remove_none(self): | CODE |
| LOW | test/test_chart_options.py | 121 | def test_graphic_text_style_opts_remove_none(self): | CODE |
| LOW | test/test_chart_options.py | 132 | def test_geo_region_opts_remove_none(self): | CODE |
| LOW⚡ | test/test_chart_options.py | 143 | def test_sunburst_label_line_opts_remove_none(self): | CODE |
| LOW⚡ | test/test_chart_options.py | 148 | def test_sunburst_label_layout_opts_remove_none(self): | CODE |
| LOW⚡ | test/test_chart_options.py | 153 | def test_sunburst_level_opts_remove_none(self): | CODE |
| LOW⚡ | test/test_chart_options.py | 158 | def test_custom_item_payload_opts_remove_none(self): | CODE |
| LOW | test/test_datasets.py | 64 | def test_fuzzy_search_key_error(self): | CODE |
| LOW | test/test_datasets.py | 76 | def test_type_error_with_non_string_key(self): | CODE |
| LOW | test/test_datasets.py | 84 | def test_type_error_with_non_string_lookfor(self): | CODE |
| LOW | test/test_wordcloud.py | 47 | def test_wordcloud_mask_image(self, fake_writer): | CODE |
| LOW | test/test_geo.py | 127 | def test_extra_geo_parameters(self, fake_writer): | CODE |
| LOW | test/test_geo.py | 157 | def test_geo_dump_options_with_quotes(self): | CODE |
| LOW | test/test_bmap.py | 51 | def test_bmap_effect_trail_length(self, fake_writer): | CODE |
| 92 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | pyecharts/__init__.py | 1 | CODE | |
| LOW | pyecharts/__init__.py | 1 | CODE | |
| LOW | pyecharts/__init__.py | 1 | CODE | |
| LOW | pyecharts/__init__.py | 1 | CODE | |
| LOW | pyecharts/__init__.py | 1 | CODE | |
| LOW | pyecharts/__init__.py | 1 | CODE | |
| LOW | pyecharts/__init__.py | 1 | CODE | |
| LOW | pyecharts/__init__.py | 2 | CODE | |
| LOW | pyecharts/__init__.py | 2 | CODE | |
| LOW | pyecharts/types.py | 1 | CODE | |
| LOW | pyecharts/types.py | 1 | CODE | |
| LOW | pyecharts/types.py | 1 | CODE | |
| LOW | pyecharts/types.py | 1 | CODE | |
| LOW | pyecharts/types.py | 1 | CODE | |
| LOW | pyecharts/types.py | 1 | CODE | |
| LOW | pyecharts/types.py | 1 | CODE | |
| LOW | pyecharts/types.py | 16 | CODE | |
| LOW | pyecharts/types.py | 16 | CODE | |
| LOW | pyecharts/types.py | 16 | CODE | |
| LOW | pyecharts/options/__init__.py | 3 | CODE | |
| LOW | pyecharts/options/__init__.py | 3 | CODE | |
| LOW | pyecharts/options/__init__.py | 3 | CODE | |
| LOW | pyecharts/options/__init__.py | 3 | CODE | |
| LOW | pyecharts/options/__init__.py | 3 | CODE | |
| LOW | pyecharts/options/__init__.py | 3 | CODE | |
| LOW | pyecharts/options/__init__.py | 3 | CODE | |
| LOW | pyecharts/options/__init__.py | 3 | CODE | |
| LOW | pyecharts/options/__init__.py | 3 | CODE | |
| LOW | pyecharts/options/__init__.py | 3 | CODE | |
| LOW | pyecharts/options/__init__.py | 3 | CODE | |
| LOW | pyecharts/options/__init__.py | 3 | CODE | |
| LOW | pyecharts/options/__init__.py | 3 | CODE | |
| LOW | pyecharts/options/__init__.py | 3 | CODE | |
| LOW | pyecharts/options/__init__.py | 3 | CODE | |
| LOW | pyecharts/options/__init__.py | 3 | CODE | |
| LOW | pyecharts/options/__init__.py | 3 | CODE | |
| LOW | pyecharts/options/__init__.py | 3 | CODE | |
| LOW | pyecharts/options/__init__.py | 3 | CODE | |
| LOW | pyecharts/options/__init__.py | 3 | CODE | |
| LOW | pyecharts/options/__init__.py | 3 | CODE | |
| LOW | pyecharts/options/__init__.py | 3 | CODE | |
| LOW | pyecharts/options/__init__.py | 3 | CODE | |
| LOW | pyecharts/options/__init__.py | 3 | CODE | |
| LOW | pyecharts/options/__init__.py | 3 | CODE | |
| LOW | pyecharts/options/__init__.py | 3 | CODE | |
| LOW | pyecharts/options/__init__.py | 3 | CODE | |
| LOW | pyecharts/options/__init__.py | 3 | CODE | |
| LOW | pyecharts/options/__init__.py | 3 | CODE | |
| LOW | pyecharts/options/__init__.py | 3 | CODE | |
| LOW | pyecharts/options/__init__.py | 3 | CODE | |
| LOW | pyecharts/options/__init__.py | 3 | CODE | |
| LOW | pyecharts/options/__init__.py | 3 | CODE | |
| LOW | pyecharts/options/__init__.py | 3 | CODE | |
| LOW | pyecharts/options/__init__.py | 3 | CODE | |
| LOW | pyecharts/options/__init__.py | 3 | CODE | |
| LOW | pyecharts/options/__init__.py | 3 | CODE | |
| LOW | pyecharts/options/__init__.py | 3 | CODE | |
| LOW | pyecharts/options/__init__.py | 3 | CODE | |
| LOW | pyecharts/options/__init__.py | 3 | CODE | |
| LOW | pyecharts/options/__init__.py | 3 | CODE | |
| 159 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | pyecharts/options/global_options.py | 23 | CODE | |
| LOW | pyecharts/options/global_options.py | 85 | CODE | |
| LOW | pyecharts/options/global_options.py | 131 | CODE | |
| LOW | pyecharts/options/global_options.py | 170 | CODE | |
| LOW | pyecharts/options/global_options.py | 224 | CODE | |
| LOW | pyecharts/options/global_options.py | 260 | CODE | |
| LOW | pyecharts/options/global_options.py | 294 | CODE | |
| LOW | pyecharts/options/global_options.py | 316 | CODE | |
| LOW | pyecharts/options/global_options.py | 351 | CODE | |
| LOW | pyecharts/options/global_options.py | 417 | CODE | |
| LOW | pyecharts/options/global_options.py | 467 | CODE | |
| LOW | pyecharts/options/global_options.py | 517 | CODE | |
| LOW | pyecharts/options/global_options.py | 577 | CODE | |
| LOW | pyecharts/options/global_options.py | 682 | CODE | |
| LOW | pyecharts/options/global_options.py | 782 | CODE | |
| LOW | pyecharts/options/global_options.py | 927 | CODE | |
| LOW | pyecharts/options/global_options.py | 999 | CODE | |
| LOW | pyecharts/options/global_options.py | 1117 | CODE | |
| LOW | pyecharts/options/global_options.py | 1181 | CODE | |
| LOW | pyecharts/options/global_options.py | 1241 | CODE | |
| LOW | pyecharts/options/global_options.py | 1285 | CODE | |
| LOW | pyecharts/options/global_options.py | 1335 | CODE | |
| LOW | pyecharts/options/global_options.py | 1394 | CODE | |
| LOW | pyecharts/options/global_options.py | 1426 | CODE | |
| LOW | pyecharts/options/global_options.py | 1458 | CODE | |
| LOW | pyecharts/options/global_options.py | 1488 | CODE | |
| LOW | pyecharts/options/global_options.py | 1530 | CODE | |
| LOW | pyecharts/options/global_options.py | 1596 | CODE | |
| LOW | pyecharts/options/global_options.py | 1661 | CODE | |
| LOW | pyecharts/options/global_options.py | 1734 | CODE | |
| LOW | pyecharts/options/global_options.py | 1832 | CODE | |
| LOW | pyecharts/options/global_options.py | 1878 | CODE | |
| LOW | pyecharts/options/global_options.py | 1946 | CODE | |
| LOW | pyecharts/options/global_options.py | 1980 | CODE | |
| LOW | pyecharts/options/global_options.py | 2018 | CODE | |
| LOW | pyecharts/options/global_options.py | 2052 | CODE | |
| LOW | pyecharts/options/charts_options.py | 46 | CODE | |
| LOW | pyecharts/options/charts_options.py | 100 | CODE | |
| LOW | pyecharts/options/charts_options.py | 418 | CODE | |
| LOW | pyecharts/options/charts_options.py | 449 | CODE | |
| LOW | pyecharts/options/charts_options.py | 603 | CODE | |
| LOW | pyecharts/options/charts_options.py | 667 | CODE | |
| LOW | pyecharts/options/charts_options.py | 719 | CODE | |
| LOW | pyecharts/options/charts_options.py | 752 | CODE | |
| LOW | pyecharts/options/charts_options.py | 803 | CODE | |
| LOW | pyecharts/options/charts_options.py | 865 | CODE | |
| LOW | pyecharts/options/charts_options.py | 889 | CODE | |
| LOW | pyecharts/options/charts_options.py | 917 | CODE | |
| LOW | pyecharts/options/charts_options.py | 965 | CODE | |
| LOW | pyecharts/options/charts_options.py | 1075 | CODE | |
| LOW | pyecharts/options/charts_options.py | 1099 | CODE | |
| LOW | pyecharts/options/charts_options.py | 1125 | CODE | |
| LOW | pyecharts/options/charts_options.py | 1158 | CODE | |
| LOW | pyecharts/options/charts_options.py | 1246 | CODE | |
| LOW | pyecharts/options/charts_options.py | 1304 | CODE | |
| LOW | pyecharts/options/charts_options.py | 1412 | CODE | |
| LOW | pyecharts/options/charts_options.py | 1468 | CODE | |
| LOW | pyecharts/options/charts_options.py | 1535 | CODE | |
| LOW | pyecharts/options/charts_options.py | 1565 | CODE | |
| LOW | pyecharts/options/charts_options.py | 1589 | CODE | |
| 50 more matches not shown… | ||||
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| HIGH | setup.py | 56 | except OSError: | CODE |
| HIGH | test/test_engine.py | 58 | except (AttributeError, AssertionError): | CODE |
| HIGH | test/test_utils.py | 77 | except ValueError: | CODE |
| HIGH | test/test_utils.py | 82 | except ValueError: | CODE |
| HIGH | test/test_display.py | 52 | except RuntimeError: | CODE |
| HIGH | test/test_custom.py | 51 | except ValueError: | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | pyecharts/commons/utils.py | 29 | CODE | |
| LOW | pyecharts/commons/utils.py | 74 | CODE | |
| LOW | pyecharts/charts/basic_charts/geo.py | 45 | CODE | |
| LOW | pyecharts/charts/basic_charts/tree.py | 17 | CODE | |
| LOW | pyecharts/charts/basic_charts/gmap.py | 31 | CODE | |
| LOW | pyecharts/charts/basic_charts/boxplot.py | 93 | CODE | |
| LOW | pyecharts/charts/basic_charts/amap.py | 31 | CODE | |
| LOW | pyecharts/charts/basic_charts/bmap.py | 32 | CODE | |
| LOW | pyecharts/charts/basic_charts/wordcloud.py | 56 | CODE | |
| LOW | pyecharts/charts/basic_charts/lmap.py | 31 | CODE | |
| LOW | pyecharts/charts/basic_charts/scatter.py | 19 | CODE | |
| LOW | pyecharts/charts/three_axis_charts/map3D.py | 21 | CODE | |
| LOW | pyecharts/render/engine.py | 30 | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| HIGH | pyecharts/charts/composite_charts/page.py | 25 | result.push({ | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | pyecharts/datasets/__init__.py | 33 | # if the item is in the dictionary then just return it | COMMENT |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | pyecharts/datasets/__init__.py | 109 | except Exception as e: | CODE |
| Severity | File | Line | Snippet | Context |
|---|---|---|---|---|
| LOW | pyecharts/render/snapshot.py | 9 | logger = logging.getLogger(__name__) | CODE |