额外的更新图方法#

使用更新方法 overwrite 现有属性#

update_layout() 和 update_trace() 有 overwrite 关键字参数,默认值为 False,在这种情况下,更新将递归地应用于现有嵌套的属性结构。当设置为 True 时,现有属性的先前值将被提供的值覆盖。

在下面的例子中,当使用 overwrite=True 更新 update_trace() 中的标记时,标记的红色会被覆盖。请注意,使用魔法下划线来设置 marker_opacity 并不会覆盖 marker_color,因为属性只会从 marker.opacity 级别开始覆写。

import plotly.graph_objects as go
go.FigureWidget(); # 初始化

fig = go.Figure(go.Bar(x=[1, 2, 3], y=[6, 4, 9],
                       marker_color="red")) # will be overwritten below

fig.update_traces(overwrite=True, marker={"opacity": 0.4})

fig.show()

有条件地更新轨迹#

假设要对轨迹集合进行的更新依赖于某些轨迹属性的当前值。update_trace() 方法不能处理这种情况,但是for_each_trace()方法可以!

作为它的第一个参数,for_each_trace() 方法每次接受并更新一个轨迹的函数。与 update_trace() 一样,for_each_trace() 也接受 selector,row 和 col 参数来控制应该考虑哪些轨迹。

下面是一个使用 for_each_trace() 将“setosa”的唯一标记转换为 Plotly Express 图中的方形符号的示例。

注意,这是可能的,因为 Plotly Express 图由输入数据帧中的每个列的单独轨迹组成。

import pandas as pd
import plotly.express as px

df = px.data.iris()

fig = px.scatter(df, x="sepal_width", y="sepal_length", color="species",
                 title="Conditionally Updating Traces In A Plotly Express Figure With for_each_trace()")

fig.for_each_trace(
    lambda trace: trace.update(marker_symbol="square") if trace.name == "setosa" else (),
)

fig.show()

更新轴#

图对象支持 update_xaxes() 和 update_yaxes() 方法,它们可用于更新图的一个或多个轴的多个嵌套属性。下面是一个使用 update_xaxes() 禁用 Plotly Express 生成的图中所有子图上的垂直网格线的示例。

import pandas as pd
import plotly.express as px

df = px.data.iris()

fig = px.scatter(df, x="sepal_width", y="sepal_length", color="species",
                 facet_col="species", title="Using update_xaxes() With A Plotly Express Figure")

fig.update_xaxes(showgrid=False)

fig.show()

还有 for_each_xaxis() 和 for_each_yaxis() 方法类似于上面描述的 for_each_trace() 方法。对于非笛卡儿子图类型(例如 polar),有额外的 update_{type} 和 for_each_{type} 方法(例如 update_polar()for_each_polar())。

其他更新方法#

使用 plot.py 图库创建的图形也支持:

链接图操作#

上面描述的所有图更新操作都是返回对正在修改的图的引用的方法。这使得将多个图形修改操作连接到一个表达式成为可能。

下面是一个创建链接表达式的示例:

  • 使用 Plotly Express 绘制带有 OLS 趋势线的 faceted scatter plot

  • 使用 update_layout() 设置标题字体大小

  • 使用 update_xaxes() 禁用垂直网格线

  • 使用 update_trace() 更新趋势线的宽度和横线模式

  • 然后使用 show() 显示图

import plotly.express as px

df = px.data.iris()

(px.scatter(df, x="sepal_width", y="sepal_length", color="species",
            facet_col="species", trendline="ols",
            title="Chaining Multiple Figure Operations With A Plotly Express Figure")
 .update_layout(title_font_size=24)
 .update_xaxes(showgrid=False)
 .update_traces(
     line=dict(dash="dot", width=4),
     selector=dict(type="scatter", mode="lines"))
).show()
---------------------------------------------------------------------------
ModuleNotFoundError                       Traceback (most recent call last)
Cell In[4], line 5
      1 import plotly.express as px
      3 df = px.data.iris()
----> 5 (px.scatter(df, x="sepal_width", y="sepal_length", color="species",
      6             facet_col="species", trendline="ols",
      7             title="Chaining Multiple Figure Operations With A Plotly Express Figure")
      8  .update_layout(title_font_size=24)
      9  .update_xaxes(showgrid=False)
     10  .update_traces(
     11      line=dict(dash="dot", width=4),
     12      selector=dict(type="scatter", mode="lines"))
     13 ).show()

File /opt/hostedtoolcache/Python/3.12.7/x64/lib/python3.12/site-packages/plotly/express/_chart_types.py:66, in scatter(data_frame, x, y, color, symbol, size, hover_name, hover_data, custom_data, text, facet_row, facet_col, facet_col_wrap, facet_row_spacing, facet_col_spacing, error_x, error_x_minus, error_y, error_y_minus, animation_frame, animation_group, category_orders, labels, orientation, color_discrete_sequence, color_discrete_map, color_continuous_scale, range_color, color_continuous_midpoint, symbol_sequence, symbol_map, opacity, size_max, marginal_x, marginal_y, trendline, trendline_options, trendline_color_override, trendline_scope, log_x, log_y, range_x, range_y, render_mode, title, template, width, height)
     12 def scatter(
     13     data_frame=None,
     14     x=None,
   (...)
     60     height=None,
     61 ) -> go.Figure:
     62     """
     63     In a scatter plot, each row of `data_frame` is represented by a symbol
     64     mark in 2D space.
     65     """
---> 66     return make_figure(args=locals(), constructor=go.Scatter)

File /opt/hostedtoolcache/Python/3.12.7/x64/lib/python3.12/site-packages/plotly/express/_core.py:2297, in make_figure(args, constructor, trace_patch, layout_patch)
   2294     elif args["ecdfnorm"] == "percent":
   2295         group[var] = 100.0 * group[var] / group_sum
-> 2297 patch, fit_results = make_trace_kwargs(
   2298     args, trace_spec, group, mapping_labels.copy(), sizeref
   2299 )
   2300 trace.update(patch)
   2301 if fit_results is not None:

File /opt/hostedtoolcache/Python/3.12.7/x64/lib/python3.12/site-packages/plotly/express/_core.py:361, in make_trace_kwargs(args, trace_spec, trace_data, mapping_labels, sizeref)
    359 trace_patch["x"] = sorted_trace_data[args["x"]][non_missing]
    360 trendline_function = trendline_functions[attr_value]
--> 361 y_out, hover_header, fit_results = trendline_function(
    362     args["trendline_options"],
    363     sorted_trace_data[args["x"]],
    364     x,
    365     y,
    366     args["x"],
    367     args["y"],
    368     non_missing,
    369 )
    370 assert len(y_out) == len(
    371     trace_patch["x"]
    372 ), "missing-data-handling failure in trendline code"
    373 trace_patch["y"] = y_out

File /opt/hostedtoolcache/Python/3.12.7/x64/lib/python3.12/site-packages/plotly/express/trendline_functions/__init__.py:43, in ols(trendline_options, x_raw, x, y, x_label, y_label, non_missing)
     37     if k not in valid_options:
     38         raise ValueError(
     39             "OLS trendline_options keys must be one of [%s] but got '%s'"
     40             % (", ".join(valid_options), k)
     41         )
---> 43 import statsmodels.api as sm
     45 add_constant = trendline_options.get("add_constant", True)
     46 log_x = trendline_options.get("log_x", False)

ModuleNotFoundError: No module named 'statsmodels'

属性赋值#

轨迹和布局属性可以使用属性赋值语法进行更新。下面是使用属性赋值设置图标题的示例。

import plotly.graph_objects as go

fig = go.Figure(data=go.Bar(x=[1, 2, 3], y=[1, 3, 2]))
fig.layout.title.text = "Using Property Assignment Syntax With A Graph Object Figure"
fig.show()

下面是使用属性赋值更新条形轮廓的例子。

import plotly.graph_objects as go

fig = go.Figure(data=go.Bar(x=[1, 2, 3], y=[1, 3, 2]))

fig.data[0].marker.line.width = 4
fig.data[0].marker.line.color = "black"

fig.show()