组件工坊:Reflex 组件库 100 例
·
课程概览
布局
·
Box
·
Flex
·
Stack
·
Grid
·
Container
·
Section
·
Center
·
Spacer
·
Separator
·
Card
·
Inset
·
Aspect Ratio
·
Fragment
排版
·
Text
·
Heading
·
Link
·
Code
·
Markdown
·
Blockquote
·
Quote
·
Strong
·
Em
·
Kbd
表单
·
Button
·
Input
·
Text Area
·
Checkbox
·
Switch
·
Radio Group
·
Select
·
Slider
·
Form
·
Upload
数据展示
·
Badge
·
Avatar
·
Icon
·
Callout
·
List
·
Data List
·
Code Block
·
Progress
·
Spinner
·
Scroll Area
·
Moment
展开与切换
·
Tabs
·
Accordion
·
Segmented Control
浮层
·
Tooltip
·
Popover
·
Hover Card
·
Dialog
·
Alert Dialog
·
Drawer
·
Dropdown Menu
·
Context Menu
·
Toast
动态渲染
·
Cond
·
Match
·
Foreach
·
Auto Scroll
媒体
·
Image
·
Audio
·
Video
表格与数据网格
·
Table
·
Data Table
·
Data Editor
图表
·
Area Chart
·
Bar Chart
·
Line Chart
·
Composed Chart
·
Pie Chart
·
Radar Chart
·
Radial Bar Chart
·
Scatter Chart
·
Funnel Chart
·
Treemap
·
Sankey Chart
·
Error Bar
图表部件
·
Axis
·
Cartesian Grid
·
Chart Tooltip
·
Legend
·
Label
·
Reference
·
Brush
其他图表库
·
Plotly
·
Pyplot
HTML 元素
·
HTML
·
HTML Text
·
HTML Layout
·
HTML Forms
·
HTML Media
·
HTML Tables
·
SVG
其他工具
·
Theme
·
Skeleton
·
Clipboard
·
Html Embed
·
Script
·
Memo
rx.plotly官方文档
工坊订单
请把各产品一年的销售额做成可以缩放查看的交互式图表,选择产品时图表随之切换。
Plotly 是用来制作可缩放、可平移、可悬停查看的交互式图表的 Python 库。rx.plotly 直接接收 Plotly 的 Figure 并在浏览器中绘制。折线、柱形等基础图表自不必说,连热力图、3D、金融图表也都不用写 JavaScript。
不像平常写脚本那样调用 fig.show(),而是在 UI 代码里用 rx.plotly(data=fig) 传入。需要的包是 plotly,本课程用 plotly.graph_objects(go)来绘图。
import plotly.graph_objects as go
plotly_years = [1952, 1957, 1962, 1967, 1972, 1977, 1982, 1987, 1992, 1997, 2002, 2007]
plotly_canada = [68.75, 69.96, 71.3, 72.13, 72.88, 74.21, 75.76, 76.86, 77.95, 78.61, 79.77, 80.65]
plotly_line_fig = go.Figure(go.Scatter(x=plotly_years, y=plotly_canada, mode="lines", name="Canada"))
plotly_line_fig.update_layout(title="Life expectancy in Canada")
rx.plotly(data=plotly_line_fig, width="100%")官方文档的示例大多使用 plotly.express(px)。px 依赖 pandas,所以本页改用 go 画出同样的图,数据则写成 Python 列表。用 px 画出的图也是 Figure,传给 rx.plotly 的方法完全一样。
给 layout 传一个 dict,会覆盖到图的布局之上。在图不变的前提下,只从界面一侧改标题、高度、背景时很方便。下面的实验台和部分示例直接使用上面的 plotly_line_fig。
试着改属性
title
height
400
showlegend
plot_bgcolor
locale
rx.plotly(
data=plotly_line_fig,
layout={"title": {"text": "Life expectancy"}, "height": 400, "showlegend": False, "plot_bgcolor": "rgba(0,0,0,0)"},
locale="en",
width="100%",
)| 属性 | 取值 | 默认值 | 用途 |
|---|---|---|---|
data | go.Figure 或其 dict | - | 要绘制的图。也可以是 State 值 |
layout | dict | - | 覆盖到图布局上的值 |
template | Plotly Template | 浅色模式 plotly,深色模式 plotly_dark | 整体配色与字体主题 |
config | dict | - | 工具栏、滚轮缩放等 Plotly 设置 |
locale | "de" "ko" … | - | 数字、日期格式和工具栏文字的语言 |
use_resize_handler | True / False | True | 窗口尺寸变化时重新适配 |
on_click · on_hover · on_unhover · on_selected · on_selecting | 事件 | - | 传入点的列表(list[dict]) |
on_relayout · on_double_click · on_deselect · on_after_plot 等 | 事件 | - | 缩放与平移、双击、取消选择、重绘之后(无参数) |
不设 template 时,Reflex 会根据浅色模式和深色模式自动切换主题。Reflex 0.10 的 rx.plotly 还有官方文档表格里没有列出的 on_click 和 on_double_click。
下面是把官方文档的 Plotly Express 示例改写成 go 的版本。无论哪种图,都同样用 rx.plotly(data=图) 传入。数据是为示例生成的值。
放入多个 go.Bar,用 barmode="group" 让它们并排。相当于 px.bar(..., color="country")。
import plotly.graph_objects as go
plotly_bar_fig = go.Figure([
go.Bar(name="Chairs", x=["Q1", "Q2", "Q3", "Q4"], y=[120, 150, 170, 210]),
go.Bar(name="Tables", x=["Q1", "Q2", "Q3", "Q4"], y=[80, 95, 130, 120]),
])
plotly_bar_fig.update_layout(barmode="group", title="Orders by quarter")
rx.plotly(data=plotly_bar_fig, width="100%")给 go.Scatter 设 mode="markers" 就只画点。每个分组各建一个 trace,颜色和图例就会分开。
import random
import plotly.graph_objects as go
plotly_scatter_rng = random.Random(7)
plotly_scatter_fig = go.Figure([
go.Scatter(
x=[plotly_scatter_rng.gauss(cx, 0.3) for _ in range(30)],
y=[plotly_scatter_rng.gauss(cy, 0.4) for _ in range(30)],
mode="markers",
name=name,
)
for name, cx, cy in [("A", 3.4, 5.0), ("B", 2.8, 5.9), ("C", 3.0, 6.6)]
])
plotly_scatter_fig.update_layout(title="Sample clusters", xaxis_title="width", yaxis_title="length")
rx.plotly(data=plotly_scatter_fig, width="100%")给 go.Pie 传入名称(labels)和数值(values),比例由 Plotly 计算。
import plotly.graph_objects as go
plotly_pie_fig = go.Figure(go.Pie(labels=["Thur", "Fri", "Sat", "Sun"], values=[171.83, 51.96, 260.40, 247.39]))
plotly_pie_fig.update_layout(title="Tips by day")
rx.plotly(data=plotly_pie_fig, width="100%")go.Histogram2d 会把两个值的组合越密集的格子涂得越深(px.density_heatmap)。如果已经有算好的表格,就用 go.Heatmap(z=...)。
import random
import plotly.graph_objects as go
plotly_heat_rng = random.Random(3)
plotly_bills = [plotly_heat_rng.gauss(20, 8) for _ in range(300)]
plotly_tips = [b * 0.15 + plotly_heat_rng.gauss(0, 0.8) for b in plotly_bills]
plotly_heatmap_fig = go.Figure(go.Histogram2d(x=plotly_bills, y=plotly_tips, nbinsx=20, nbinsy=15))
plotly_heatmap_fig.update_layout(title="Bill vs tip density heatmap")
rx.plotly(data=plotly_heatmap_fig, width="100%")go.Histogram 把数值划分成区间并计数。nbinsx 是区间数的上限。
import random
import plotly.graph_objects as go
plotly_hist_rng = random.Random(5)
plotly_hist_fig = go.Figure(go.Histogram(x=[plotly_hist_rng.gauss(20, 8) for _ in range(250)], nbinsx=20))
plotly_hist_fig.update_layout(title="Distribution of total bills")
rx.plotly(data=plotly_hist_fig, width="100%")go.Box 用一个箱子展示中位数、四分位数和离群值。每个分组各放一个 trace。
import random
import plotly.graph_objects as go
plotly_box_rng = random.Random(11)
plotly_box_fig = go.Figure([
go.Box(y=[plotly_box_rng.gauss(mean, 6) for _ in range(40)], name=day)
for day, mean in [("Thur", 17), ("Fri", 17), ("Sat", 20), ("Sun", 21)]
])
plotly_box_fig.update_layout(title="Total bill by day")
rx.plotly(data=plotly_box_fig, width="100%")在散点图里用点的大小(marker.size)表示第三个值。把 x 轴改成 type="log",就等同于 px.scatter(..., log_x=True)。
import plotly.graph_objects as go
plotly_bubble_fig = go.Figure(go.Scatter(
x=[800, 2500, 6000, 15000, 32000, 45000],
y=[52, 61, 68, 74, 79, 82],
text=["A", "B", "C", "D", "E", "F"],
mode="markers",
marker={"size": [20, 45, 30, 60, 25, 40], "color": [1, 2, 3, 4, 5, 6], "colorscale": "Viridis"},
))
plotly_bubble_fig.update_xaxes(type="log", title="income")
plotly_bubble_fig.update_layout(title="Income vs life expectancy", yaxis_title="years")
rx.plotly(data=plotly_bubble_fig, width="100%")日程表用横向柱形(orientation="h")来画。柱子的起点是 base,长度是以毫秒计的时长,x 轴设为日期轴。这正是 px.timeline 在内部做的事。再把 y 轴反转,让它从上往下读。
from datetime import date
import plotly.graph_objects as go
plotly_jobs = [("Job A", "2009-01-01", "2009-02-28"), ("Job B", "2009-03-05", "2009-04-15"), ("Job C", "2009-02-20", "2009-05-30")]
plotly_gantt_fig = go.Figure(go.Bar(
y=[job for job, start, end in plotly_jobs],
base=[start for job, start, end in plotly_jobs],
x=[(date.fromisoformat(end) - date.fromisoformat(start)).days * 86_400_000 for job, start, end in plotly_jobs],
orientation="h",
))
plotly_gantt_fig.update_xaxes(type="date")
plotly_gantt_fig.update_yaxes(autorange="reversed")
rx.plotly(data=plotly_gantt_fig, width="100%")把层级数据从中心的根向外圈展开。用 labels 和 parents 写出父子关系。
import plotly.graph_objects as go
plotly_sunburst_fig = go.Figure(go.Sunburst(
labels=["Eve", "Cain", "Seth", "Enos", "Noam", "Abel", "Awan", "Enoch", "Azura"],
parents=["", "Eve", "Eve", "Seth", "Seth", "Eve", "Eve", "Awan", "Eve"],
values=[10, 14, 12, 10, 2, 6, 6, 4, 4],
))
rx.plotly(data=plotly_sunburst_fig, width="100%")展示从访问到购买的每个阶段减少了多少。适合找出在哪个阶段流失最多。
import plotly.graph_objects as go
plotly_funnel_fig = go.Figure(go.Funnel(
x=[39, 27.4, 20.6, 11, 2],
y=["Website visit", "Downloads", "Potential customers", "Requested price", "Invoice sent"],
))
rx.plotly(data=plotly_funnel_fig, width="100%")locale 会把数字、日期格式和工具栏提示文字换成对应语言。下面是德语。也可以同时设 config;两者都有时,locale 的值最后生效。
rx.plotly(data=plotly_line_fig, locale="de", width="100%")给 go.Surface 传入高度值的二维列表(z),就成了曲面。官方文档读取的是 CSV 文件里的山体高度数据,这里使用公式生成的值。可以拖动旋转查看。
import math
import plotly.graph_objects as go
plotly_surface_z = [[60 + 40 * math.sin(x / 4) * math.cos(y / 5) + y for x in range(30)] for y in range(30)]
plotly_surface_fig = go.Figure(data=[go.Surface(z=plotly_surface_z)])
plotly_surface_fig.update_traces(contours_z=dict(show=True, usecolormap=True, highlightcolor="limegreen", project_z=True))
plotly_surface_fig.update_layout(scene_camera_eye=dict(x=1.87, y=0.88, z=-0.64), margin=dict(l=65, r=50, b=65, t=90))
rx.plotly(data=plotly_surface_fig, width="100%")每个日期用一根蜡烛画出开盘价、最高价、最低价和收盘价。实体在开盘价与收盘价之间,影线在最低价与最高价之间。
import plotly.graph_objects as go
plotly_candle_fig = go.Figure(go.Candlestick(
x=["2024-01-02", "2024-01-03", "2024-01-04", "2024-01-05", "2024-01-08", "2024-01-09"],
open=[187.15, 184.22, 182.15, 181.99, 182.09, 183.92],
high=[188.44, 185.88, 183.09, 182.76, 185.60, 185.15],
low=[183.89, 183.43, 180.88, 180.17, 181.50, 182.73],
close=[185.64, 184.25, 181.91, 181.18, 185.56, 185.14],
))
plotly_candle_fig.update_layout(title=dict(text="Stock price"), yaxis=dict(title=dict(text="USD")))
rx.plotly(data=plotly_candle_fig, width="100%")展示初始值经过各项加减后如何变化。用 measure 指定每一项是变化量("relative")还是合计("total")。
import plotly.graph_objects as go
plotly_waterfall_fig = go.Figure(go.Waterfall(
name="2018",
orientation="v",
measure=["relative", "relative", "total", "relative", "relative", "total"],
x=["Sales", "Consulting", "Net revenue", "Purchases", "Other expenses", "Profit before tax"],
textposition="outside",
text=["+60", "+80", "", "-40", "-20", "Total"],
y=[60, 80, 0, -40, -20, 0],
connector={"line": {"color": "rgb(63, 63, 63)"}},
))
plotly_waterfall_fig.update_layout(title="Profit and loss statement 2018", showlegend=True)
rx.plotly(data=plotly_waterfall_fig, width="100%")用来代替仪表盘的小型条形图。给 go.Indicator 设上 gauge.shape="bullet",把实际值条、区间(steps)和目标线(threshold)放在同一行里。
import plotly.graph_objects as go
plotly_bullet_fig = go.Figure(go.Indicator(
mode="number+gauge+delta",
value=180,
delta={"reference": 200},
domain={"x": [0.25, 1], "y": [0.4, 0.6]},
title={"text": "Revenue"},
gauge={
"shape": "bullet",
"axis": {"range": [None, 300]},
"threshold": {"line": {"color": "black", "width": 2}, "thickness": 0.75, "value": 170},
"steps": [{"range": [0, 150], "color": "gray"}, {"range": [150, 250], "color": "lightgray"}],
"bar": {"color": "black"},
},
))
plotly_bullet_fig.update_layout(height=250)
rx.plotly(data=plotly_bullet_fig, width="100%")不用误差棒,而是用线条周围的浅色带来表示误差。把上边界正向、下边界反向连起来,组成一条绕一圈的线,再用 fill="toself" 填充内部。
import plotly.graph_objects as go
plotly_band_x = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
plotly_band_y = [1, 2, 7, 4, 5, 6, 7, 8, 9, 10]
plotly_band_upper = [2, 3, 8, 5, 6, 7, 8, 9, 10, 11]
plotly_band_lower = [0, 1, 5, 3, 4, 5, 6, 7, 8, 9]
plotly_band_fig = go.Figure([
go.Scatter(x=plotly_band_x, y=plotly_band_y, line=dict(color="rgb(0,100,80)"), mode="lines"),
go.Scatter(
x=plotly_band_x + plotly_band_x[::-1],
y=plotly_band_upper + plotly_band_lower[::-1],
fill="toself",
fillcolor="rgba(0,100,80,0.2)",
line=dict(color="rgba(255,255,255,0)"),
hoverinfo="skip",
showlegend=False,
),
])
rx.plotly(data=plotly_band_fig, width="100%")Plotly 的地图在绘制时会从外部服务器获取地图数据。轮廓地图(Scattergeo、Choropleth)使用 Plotly CDN 的地形数据,瓦片地图(Scattermap)使用地图瓦片服务器。本课程不使用外部资源,所以只展示代码。在应用中可以照常运行。
轮廓地图的设置在图的 layout.geo 中,用 update_geos 调整湖泊、河流等显示。
import plotly.graph_objects as go
geo_fig = go.Figure(go.Scattergeo())
geo_fig.update_geos(
visible=False,
resolution=50,
showlakes=True,
lakecolor="Blue",
showrivers=True,
rivercolor="Blue",
)
geo_fig.update_layout(height=300, margin={"r": 0, "t": 0, "l": 0, "b": 0})
def geo_map_chart():
return rx.plotly(data=geo_fig, width="100%")在瓦片地图上打点。官方文档用的是 px.scatter_map,用 go 则是 go.Scattermap。地图样式在 layout.map 中设定。
import plotly.graph_objects as go
map_fig = go.Figure(go.Scattermap(
lat=[37.57, 35.18, 35.87],
lon=[126.98, 129.08, 128.60],
text=["Seoul", "Busan", "Daegu"],
mode="markers",
marker={"size": [18, 12, 10]},
))
map_fig.update_layout(
map={"style": "open-street-map", "center": {"lat": 36.4, "lon": 127.8}, "zoom": 5},
margin={"r": 0, "t": 0, "l": 0, "b": 0},
)
def scatter_map_chart():
return rx.plotly(data=map_fig, width="100%")go.Table 在 header 里接收列名,在 cells 里接收每一列的值列表。支持滚动和调整列顺序。
import plotly.graph_objects as go
plotly_table_fig = go.Figure(go.Table(
header=dict(values=["A Scores", "B Scores"]),
cells=dict(values=[[100, 90, 80, 90], [95, 85, 75, 95]]),
))
rx.plotly(data=plotly_table_fig, width="100%")用带子的粗细表示流量大小。在 node.label 里写节点名称,在 link 中用节点序号把 source→target 连起来。
import plotly.graph_objects as go
plotly_sankey_fig = go.Figure(go.Sankey(
node=dict(pad=15, thickness=20, line=dict(color="black", width=0.5), label=["A1", "A2", "B1", "B2", "C1", "C2"], color="blue"),
link=dict(source=[0, 1, 0, 2, 3, 3], target=[2, 3, 3, 4, 4, 5], value=[8, 4, 2, 8, 4, 2]),
))
plotly_sankey_fig.update_layout(title_text="Basic Sankey Diagram", font_size=10)
rx.plotly(data=plotly_sankey_fig, width="100%")go.Scatter3d 把三个值之间的关系画在空间里(px.scatter_3d)。
import random
import plotly.graph_objects as go
plotly_s3d_rng = random.Random(2)
plotly_s3d_fig = go.Figure([
go.Scatter3d(
x=[plotly_s3d_rng.gauss(cx, 0.4) for _ in range(30)],
y=[plotly_s3d_rng.gauss(cy, 0.3) for _ in range(30)],
z=[plotly_s3d_rng.gauss(cz, 0.3) for _ in range(30)],
mode="markers",
marker={"size": 4},
name=name,
)
for name, cx, cy, cz in [("A", 5.0, 3.4, 0.2), ("B", 5.9, 2.8, 1.3), ("C", 6.6, 3.0, 2.0)]
])
rx.plotly(data=plotly_s3d_fig, width="100%")3D 图的坐标轴位于 scene 之中。像 scene.xaxis 这样,为每根轴设定 nticks(刻度数)和 range(范围)。官方文档用的是 numpy 随机数,这里用 random 实现同样的效果。
import random
import plotly.graph_objects as go
plotly_mesh_rng = random.Random(1)
plotly_mesh_fig = go.Figure(go.Mesh3d(
x=[70 * plotly_mesh_rng.gauss(0, 1) for _ in range(70)],
y=[55 * plotly_mesh_rng.gauss(0, 1) for _ in range(70)],
z=[40 * plotly_mesh_rng.gauss(0, 1) for _ in range(70)],
opacity=0.5,
color="rgba(244,22,100,0.6)",
))
plotly_mesh_fig.update_layout(
scene=dict(
xaxis=dict(nticks=4, range=[-100, 100]),
yaxis=dict(nticks=4, range=[-50, 100]),
zaxis=dict(nticks=4, range=[-100, 100]),
),
margin=dict(r=20, l=10, b=10, t=10),
)
rx.plotly(data=plotly_mesh_fig, width="100%")把图放进 State 值,就能在运行时修改。官方文档把 go.Figure 存进 State 变量,这里只在 State 里放一个数字,由 @rx.var 计算值来生成图。拖动滑块,计算值会重新生成,图表随之改变。
import math
import plotly.graph_objects as go
class PlotlyWaveState(rx.State):
cycles: int = 2
@rx.event
def set_cycles(self, value: list[float]):
self.cycles = int(value[0])
@rx.var
def figure(self) -> go.Figure:
xs = [i / 50 for i in range(101)]
fig = go.Figure(go.Scatter(x=xs, y=[math.sin(2 * math.pi * self.cycles * x) for x in xs], mode="lines"))
fig.update_layout(title=f"{self.cycles} cycles", height=300)
return fig
rx.vstack(
rx.slider(value=[PlotlyWaveState.cycles], min=1, max=8, step=1, on_change=PlotlyWaveState.set_cycles, width="240px"),
rx.plotly(data=PlotlyWaveState.figure, width="100%"),
width="100%",
)on_click、on_hover、on_selected 会传来触发事件的点的列表。每个点里都有 x、y、curveNumber(第几个 trace)、pointNumber(第几个点)等值。
import plotly.graph_objects as go
plotly_click_fig = go.Figure(go.Bar(x=["Mon", "Tue", "Wed", "Thu", "Fri"], y=[12, 19, 7, 15, 22]))
plotly_click_fig.update_layout(height=280)
class PlotlyClickState(rx.State):
picked: str = "Click a bar"
@rx.event
def pick(self, points: list[dict]):
if points:
point = points[0]
self.picked = f"{point['x']}: {point['y']}"
rx.vstack(
rx.plotly(data=plotly_click_fig, on_click=PlotlyClickState.pick, width="100%"),
rx.badge(PlotlyClickState.picked, size="2"),
width="100%",
)外观在创建图时用 update_layout() 设定。标题位置(title_x)、绘图区与外部背景色、字体等所有布局属性,都在 Plotly Layout 文档里。
与其给 rx.plotly 的宽高设固定值,不如让它跟随外层容器的尺寸,这样才能随屏幕大小伸缩。
import plotly.graph_objects as go
plotly_styled_fig = go.Figure(go.Scatter(
x=[1952, 1957, 1962, 1967, 1972, 1977, 1982, 1987, 1992, 1997, 2002, 2007],
y=[68.75, 69.96, 71.3, 72.13, 72.88, 74.21, 75.76, 76.86, 77.95, 78.61, 79.77, 80.65],
mode="lines",
name="Canada",
))
plotly_styled_fig.update_layout(
title="Life expectancy in Canada",
title_x=0.5,
plot_bgcolor="#c3d7f7",
paper_bgcolor="rgba(128, 128, 128, 0.1)",
showlegend=True,
title_font_family="Open Sans",
title_font_size=25,
)
rx.plotly(data=plotly_styled_fig, width="100%")Reflex 0.10 还提供只包含所需 trace 的轻量包。rx.plotly.basic、rx.plotly.cartesian、rx.plotly.finance、rx.plotly.geo、rx.plotly.gl2d、rx.plotly.gl3d、rx.plotly.mapbox、rx.plotly.strict 接受与 rx.plotly 相同的属性,同时减少浏览器的下载量(官方文档里还没有)。
State 里只放选中的产品名,由计算值同时画出月度柱形和累计折线。累计折线用右侧的轴(yaxis2),再用 hovermode="x unified" 把同一个月的数值汇总到一个框里。
import plotly.graph_objects as go
plotly_months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
plotly_sales = {
"Chairs": [32, 41, 38, 52, 61, 58, 70, 66, 59, 73, 88, 95],
"Tables": [12, 15, 21, 19, 24, 30, 28, 33, 35, 31, 40, 46],
"Lamps": [55, 50, 47, 44, 49, 53, 60, 58, 62, 67, 80, 102],
}
class PlotlyOrderState(rx.State):
product: str = "Chairs"
@rx.event
def set_product(self, value: str):
self.product = value
@rx.var
def figure(self) -> go.Figure:
monthly = plotly_sales[self.product]
running = [sum(monthly[: i + 1]) for i in range(len(monthly))]
fig = go.Figure([
go.Bar(x=plotly_months, y=monthly, name="Monthly"),
go.Scatter(x=plotly_months, y=running, name="Running total", yaxis="y2", mode="lines+markers"),
])
fig.update_layout(
title=f"{self.product} sales",
hovermode="x unified",
yaxis2={"overlaying": "y", "side": "right"},
legend={"orientation": "h", "y": -0.2},
height=360,
)
return fig
rx.vstack(
rx.select(["Chairs", "Tables", "Lamps"], value=PlotlyOrderState.product, on_change=PlotlyOrderState.set_product),
rx.plotly(data=PlotlyOrderState.figure, width="100%"),
width="100%",
)工坊笔记
用 rx.plotly(data=fig) 代替 fig.show()。用 go 画的图和用 px 画的图都一样。
用 layout=dict 覆盖布局,用 locale 改变数字格式和工具栏语言。
State 里放简单的值,让 @rx.var 计算值返回 go.Figure,图表就会随之更新。
on_click、on_hover、on_selected 会传来点的列表(x、y、curveNumber、pointNumber …)。
地图会从外部获取地图数据。主题会随浅色、深色模式自动切换。
订阅新课时和新课程通知
本课程新增课时或推出后续课程时,我们会发邮件通知你。
问答
关于本课有任何疑问都可以在这里留言。所有语言版本页面的提问会汇集在一起。