此文接着上面的文章(一)开始写:
go里面的Scatter与Line
在go的写法里面,可以通过go.Scatter(mode = 'lines+markers')来制定线型。
而go.Line又是可以直接输出线段的。那么二者的区别是什么呢?
这里可以将go.Line理解成Scatter(mode="lines")的"别名"或者"快捷方式"。Line是提前封装好的Scatter中的line类型。而Scatter是一个创建所有线型的方法,通过设置属性可以实现几乎所有的绘图。
下面补充一下各方法的属性:
import plotly.graph_objects as go
print(dir(go))
['AngularAxis', 'Annotation', 'Annotations', 'Bar', 'Barpolar', 'Box', 'Candlestick', 'Carpet', 'Choropleth', 'Choroplethmap',
'Choroplethmapbox', 'ColorBar', 'Cone', 'Contour', 'Contourcarpet', 'Contours', 'Data', 'Densitymap', 'Densitymapbox',
'ErrorX', 'ErrorY', 'ErrorZ', 'Figure', 'FigureWidget', 'Font', 'Frame', 'Frames', 'Funnel', 'Funnelarea', 'Heatmap',
'Histogram', 'Histogram2d', 'Histogram2dContour', 'Histogram2dcontour', 'Icicle', 'Image', 'Indicator', 'Isosurface',
'Layout', 'Legend', 'Line', 'Margin', 'Marker', 'Mesh3d', 'Ohlc', 'Parcats', 'Parcoords', 'Pie', 'RadialAxis', 'Sankey',
'Scatter', 'Scatter3d', 'Scattercarpet', 'Scattergeo', 'Scattergl', 'Scattermap', 'Scattermapbox', 'Scatterpolar',
'Scatterpolargl', 'Scattersmith', 'Scatterternary', 'Scene', 'Splom', 'Stream', 'Streamtube', 'Sunburst', 'Surface', 'Table',
'Trace', 'Treemap', 'Violin', 'Volume', 'Waterfall', 'XAxis', 'XBins', 'YAxis', 'YBins', 'ZAxis', 'bar', 'barpolar', 'box',
'candlestick', 'carpet', 'choropleth', 'choroplethmap', 'choroplethmapbox', 'cone', 'contour', 'contourcarpet',
'densitymap', 'densitymapbox', 'funnel', 'funnelarea', 'heatmap', 'histogram', 'histogram2d', 'histogram2dcontour',
'icicle', 'image', 'indicator', 'isosurface', 'layout', 'mesh3d', 'ohlc', 'parcats', 'parcoords', 'pie', 'sankey', 'scatter',
'scatter3d', 'scattercarpet', 'scattergeo', 'scattergl', 'scattermap', 'scattermapbox', 'scatterpolar', 'scatterpolargl',
'scattersmith', 'scatterternary', 'splom', 'streamtube', 'sunburst', 'surface', 'table', 'treemap', 'violin', 'volume', 'waterfall']
import plotly.graph_objects as go
print(dir(go.Scatter))
['__class__', '__contains__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__',
'__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__lt__',
'__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setitem__',
'__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_build_repr_for_class', '_dispatch_change_callbacks',
'_dispatch_on_click', '_dispatch_on_deselect', '_dispatch_on_hover', '_dispatch_on_selection',
'_dispatch_on_unhover', '_get_child_prop_defaults', '_get_child_props', '_get_prop_validator', '_get_validator',
'_in_batch_mode', '_init_child_props', '_init_props', '_mapped_properties', '_parent_path_str', '_path_str',
'_process_kwargs', '_prop_defaults', '_prop_descriptions', '_prop_set_child', '_props',
'_raise_on_invalid_property_error', '_relayout_child', '_restyle_child', '_send_prop_set', '_set_array_prop',
'_set_compound_prop', '_set_prop', '_set_property', '_valid_props', '_validators', '_vals_equal', 'alignmentgroup',
'cliponaxis', 'connectgaps', 'customdata', 'customdatasrc', 'dx', 'dy', 'error_x', 'error_y', 'figure', 'fill', 'fillcolor',
'fillgradient', 'fillpattern', 'groupnorm', 'hoverinfo', 'hoverinfosrc', 'hoverlabel', 'hoveron', 'hovertemplate',
'hovertemplatesrc', 'hovertext', 'hovertextsrc', 'ids', 'idssrc', 'legend', 'legendgroup', 'legendgrouptitle', 'legendrank',
'legendwidth', 'line', 'marker', 'meta', 'metasrc', 'mode', 'name', 'offsetgroup', 'on_change', 'on_click', 'on_deselect',
'on_hover', 'on_selection', 'on_unhover', 'opacity', 'orientation', 'parent', 'plotly_name', 'pop', 'selected', 'selectedpoints',
'showlegend', 'stackgaps', 'stackgroup', 'stream', 'text', 'textfont', 'textposition', 'textpositionsrc', 'textsrc', 'texttemplate',
'texttemplatesrc', 'to_json', 'to_plotly_json', 'type', 'uid', 'uirevision', 'unselected', 'update', 'visible', 'x', 'x0', 'xaxis',
'xcalendar', 'xhoverformat', 'xperiod', 'xperiod0', 'xperiodalignment', 'xsrc', 'y', 'y0', 'yaxis', 'ycalendar', 'yhoverformat',
'yperiod', 'yperiod0', 'yperiodalignment', 'ysrc', 'zorder']
import plotly.graph_objects as go
print(dir(go.Figure))
['__class__', '__contains__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__',
'__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__lt__',
'__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setitem__',
'__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_add_annotation_like', '_allow_disable_validation',
'_bracket_re', '_build_dispatch_plan', '_build_update_params_from_batch', '_dispatch_layout_change_callbacks',
'_dispatch_trace_change_callbacks', '_filter_by_selector', '_get_child_prop_defaults', '_get_child_props',
'_get_subplot_coordinates', '_get_subplot_rows_columns', '_has_subplots', '_index_is', '_init_child_props',
'_initialize_layout_template', '_ipython_display_', '_is_dict_list', '_is_key_path_compatible',
'_make_axis_spanning_layout_object', '_normalize_trace_indexes', '_perform_batch_animate',
'_perform_plotly_relayout', '_perform_plotly_restyle', '_perform_plotly_update', '_perform_select_traces',
'_perform_update', '_process_multiple_axis_spanning_shapes', '_raise_invalid_rows_cols', '_relayout_child',
'_repr_html_', '_repr_mimebundle_', '_restyle_child', '_select_annotations_like', '_select_layout_subplots_by_prefix',
'_select_subplot_coordinates', '_selector_matches', '_send_addTraces_msg', '_send_animate_msg',
'_send_deleteTraces_msg', '_send_moveTraces_msg', '_send_relayout_msg', '_send_restyle_msg',
'_send_update_msg', '_set_in', '_set_property', '_set_trace_grid_position', '_set_trace_uid', '_str_to_dict_path',
'_subplot_not_empty', '_to_ordered_dict', '_valid_underscore_properties', '_validate_get_grid_ref',
'_validate_rows_cols', 'add_annotation', 'add_bar', 'add_barpolar', 'add_box', 'add_candlestick', 'add_carpet',
'add_choropleth', 'add_choroplethmap', 'add_choroplethmapbox', 'add_cone', 'add_contour', 'add_contourcarpet',
'add_densitymap', 'add_densitymapbox', 'add_funnel', 'add_funnelarea', 'add_heatmap', 'add_histogram',
'add_histogram2d', 'add_histogram2dcontour', 'add_hline', 'add_hrect', 'add_icicle', 'add_image', 'add_indicator',
'add_isosurface', 'add_layout_image', 'add_mesh3d', 'add_ohlc', 'add_parcats', 'add_parcoords', 'add_pie',
'add_sankey', 'add_scatter', 'add_scatter3d', 'add_scattercarpet', 'add_scattergeo', 'add_scattergl', 'add_scattermap',
'add_scattermapbox', 'add_scatterpolar', 'add_scatterpolargl', 'add_scattersmith', 'add_scatterternary', 'add_selection',
'add_shape', 'add_splom', 'add_streamtube', 'add_sunburst', 'add_surface', 'add_table', 'add_trace', 'add_traces',
'add_treemap', 'add_violin', 'add_vline', 'add_volume', 'add_vrect', 'add_waterfall', 'append_trace', 'batch_animate',
'batch_update', 'data', 'for_each_annotation', 'for_each_coloraxis', 'for_each_geo', 'for_each_layout_image',
'for_each_legend', 'for_each_map', 'for_each_mapbox', 'for_each_polar', 'for_each_scene', 'for_each_selection',
'for_each_shape', 'for_each_smith', 'for_each_ternary', 'for_each_trace', 'for_each_xaxis', 'for_each_yaxis', 'frames',
'full_figure_for_development', 'get_subplot', 'layout', 'plotly_relayout', 'plotly_restyle', 'plotly_update', 'pop', 'print_grid',
'select_annotations', 'select_coloraxes', 'select_geos', 'select_layout_images', 'select_legends', 'select_mapboxes',
'select_maps', 'select_polars', 'select_scenes', 'select_selections', 'select_shapes', 'select_smiths', 'select_ternaries',
'select_traces', 'select_xaxes', 'select_yaxes', 'set_subplots', 'show', 'to_dict', 'to_html', 'to_image', 'to_json',
'to_ordered_dict', 'to_plotly_json', 'update', 'update_annotations', 'update_coloraxes', 'update_geos', 'update_layout',
'update_layout_images', 'update_legends', 'update_mapboxes', 'update_maps', 'update_polars', 'update_scenes',
'update_selections', 'update_shapes', 'update_smiths', 'update_ternaries', 'update_traces', 'update_xaxes',
'update_yaxes', 'write_html', 'write_image', 'write_json']
样式的多层嵌套
之前提到的样式可以进行多层的嵌套。
我们定制一个 go.Scatter 图表中的标记 (Marker),通过三层嵌套来精确控制标记的颜色、边缘线的粗细和颜色。
多层属性嵌套案例:定制标记 (Marker)
场景:绘制散点图,要求每个数据点(标记)具有以下样式:
- 标记主体: 颜色为 淡黄色 (
'#FFFFE0')。 - 标记边缘线: 颜色为 深红色 (
'#8B0000')。 - 标记边缘线: 宽度为 3 像素。
嵌套路径分析
要实现这个定制,我们需要遵循以下嵌套路径:
go.Scatter→marker→line→color/width\text{go.Scatter} \rightarrow \mathbf{\text{marker}} \rightarrow \mathbf{\text{line}} \rightarrow \text{color/width}go.Scatter→marker→line→color/width
| 层级 | 属性 (键) | 作用 | 类型 |
|---|---|---|---|
| 轨迹层 | go.Scatter |
容纳所有数据和样式。 | 对象 |
| 第一层嵌套 | marker |
控制标记的整体样式。 | 字典 (dict) |
| 第二层嵌套 | marker 内的 line |
控制标记边缘线的样式。 | 字典 (dict) |
| 第三层嵌套 | marker.line 内的 color |
控制边缘线的颜色。 | 字符串 |
| 第三层嵌套 | marker.line 内的 width |
控制边缘线的宽度。 | 数字 |
python
import plotly.graph_objects as go
import numpy as np
# 假设数据
np.random.seed(42)
x_data = np.arange(10)
y_data = np.random.rand(10) * 10
# 使用 go.Scatter 创建轨迹
trace = go.Scatter(
x=x_data,
y=y_data,
mode='markers', # 确保只显示标记
# ✨ 第一层嵌套:Marker 属性
marker=dict(
size=15, # 标记大小 (顶级标记属性)
color='#FFFFE0', # 标记主体颜色 (顶级标记属性)
# ✨ 第二层嵌套:Marker 边缘线 (line) 属性
line=dict(
# ✨ 第三层嵌套:边缘线的颜色和宽度
color='#8B0000', # 边缘线颜色
width=3 # 边缘线宽度
)
),
name='多层嵌套定制示例'
)
fig = go.Figure(data=[trace])
fig.update_layout(title='Plotly 三层嵌套定制:标记边缘样式')
fig.show()
通过这个案例,我们看到 Plotly 如何使用嵌套字典(或对象)来实现对图表元素的精细控制:
- 从
go.Scatter开始。 - 要控制标记,进入了
marker字典。 - 要控制标记的边缘线,又进入了
marker字典内的line字典。
只要知道目标属性的正确嵌套路径,我们就可以定制 Plotly 图表中的任何元素。