Plotly 图形组件不能接受视口单位来设置文本注释字体大小
Posted
技术标签:
【中文标题】Plotly 图形组件不能接受视口单位来设置文本注释字体大小【英文标题】:Plotly graph component cannot accept viewport units to set text annotation font size 【发布时间】:2019-05-25 21:10:59 【问题描述】:我正在使用 Plotly-Dash 并且需要我的文本注释的字体大小与视口宽度一起缩放,就像我的图表一样。对于我布局中的各种标题,我可以直接设置font-size: '1vw'
,但是vw
不是为style
组件的style
属性设置font-size
的可接受单位。这是相关的回溯:
值错误: 为 scatter.textfont 的“大小”属性接收到无效元素 无效元素包括:['1vw', '1vw', '1vw', '1vw', '1vw', '1vw', '1vw', '1vw', '1vw', '1vw']
The 'size' property is a number and may be specified as: - An int or float in the interval [1, inf] - A tuple, list, or one-dimensional numpy array of the above
我认为如果dcc.Graph
组件可以接受视口单位(例如style = height: 30vw, width: 30vw
)并简单地将它们转换为浏览器端的像素,那么我应该能够使用font-size
执行类似的转换。
在 Python 端是否有一种方法可以检索视口宽度(以像素为单位),以便我可以针对字体大小执行自己的缩放逻辑?
以下是演示此行为的示例 Dash 应用程序:
import dash
from dash.dependencies import Input, Output
import dash_core_components as dcc
import dash_html_components as html
import plotly.graph_objs as go
labels = 'Point 1': (3.5,5), 'Point 2': (1.5,2), 'Point 3': (3.5,8)
app = dash.Dash(__name__)
app.layout = html.Div([
html.H1('Test', id='test', style='margin': 50),
dcc.Graph(id='my-plot', style='margin': 10),
])
@app.callback(
Output('my-plot', 'figure'),
[Input('test', 'children')])
def update_graph(val):
return
'data': [go.Scatter(
x=[v[0]],
y=[v[1]],
text=k,
mode='text'
) for k, v in labels.items()],
'layout': go.Layout(
margin='l': 40, 'b': 40, 't': 40, 'r': 40,
shapes=[
'type': 'path',
'path': ' M 1 1 L 1 3 L 4 1 Z',
'fillcolor': 'rgba(44, 160, 101, 0.5)',
'line':
'color': 'rgb(44, 160, 101)',
,
'type': 'path',
'path': ' M 3,7 L2,8 L2,9 L3,10, L4,10 L5,9 L5,8 L4,7 Z',
'fillcolor': 'rgba(255, 140, 184, 0.5)',
'line':
'color': 'rgb(255, 140, 184)',
,
]
)
if __name__ == '__main__':
app.run_server()
【问题讨论】:
能否提供带有文本注释的示例运行代码? 如果此时此问题仍然是相对的,您可以使用 javascript 来解决。只需使用观察者在px
中检查浏览器的视口width
,将px
的值放在let
中,然后将其应用于font-size
的dcc.Graph
感谢您迄今为止的回复,我已经添加了一个示例 Dash 应用程序,应该作为一个工作示例。
【参考方案1】:
据我了解,仅使用plotly-dash
是无法做到这一点的。
您需要实现的基本上是“响应式”排版,这个主题有一些非常有趣的文章:
em
单位:https://developer.mozilla.org/en-US/docs/Web/CSS/font-size#Ems
Dash 提供了一个应用程序的option to override the default CSS and JS,您可以从layout documentation 看到,如何使用甚至是外部 CSS 文件。
我的建议: 研究结果页面,找出文本注释是如何被标记的(id
和/或class
),并使用上述文章中提供的方法来创建令人满意的结果. (很抱歉,除了建议,我真的无能为力,但我还没有看到你的代码示例:/)
编辑(评论和问题编辑后):
因此,由于文本注释具有 textpoint
类,我们将使用 override the default CSS:
创建建议的文件夹结构:
- app.py
- assets/
|--- typography.css
在typography.css
上应用上述方法之一(我将通过第二个项目符号示例):
.textpoint
font-size: calc(14px + (26 - 14) * ((100vw - 300px) / (1600 - 300)));
编辑 #2:
我发现了问题和解决方法:
在 Dash 版本 >= 0.22 上添加自定义 CSS 的方法确实是上面的,并且有效。 为了将自定义规则应用于注释,我们需要定位的元素是.textpoint
类中的text
标记(CSS 语法:.textpoint text
)
由于某种原因,自定义 CSS 规则被覆盖(可能出于类似原因,在此 SO 帖子的顶部答案中进行了解释:custom css being overridden by bootstrap css)。所以我们需要!important
的“核”选项。
利用上述内容,typography.css
应如下所示:
.textpoint text
font-size: calc(14px + (26 - 14) * ((100vw - 300px) / (1600 - 300))) !important;
【讨论】:
我在我的帖子中添加了一个示例 Dash 应用程序。感谢您迄今为止的周到回复。似乎文本注释被标记为 w/class="textpoint"
@rahlf23 感谢您的更新,我已相应地编辑了我的答案。
由于某种原因,这似乎对我不起作用。在您上面的回答中,typography.css
文件的完整内容正确吗?
您是否能够在您的终端上生成一个有效的 Dash 应用程序,其中文本注释实际上会根据视口宽度调整大小?不幸的是,他们不在我这边。
@rahlf23 您应该删除应用程序初始化的external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
和external_stylesheets=external_stylesheets
部分,因为该外部CSS 上的说明可能会覆盖自定义的说明?【参考方案2】:
错误消息说您应该将大小作为int
对象提及。
如果您不能在代码中直接使用 vw,请尝试使用 PySide / PyQt 获取它,然后将其转换为 int
并将其保存在另一个变量 width
和 height
下,您可以插入该变量而不是 @ 987654325@.
from PySide import QtGui
#replace that with "from PyQt4 import QtGui" if you're using PyQt4
app = QtGui.QApplication([])
screen_resolution = app.desktop().screenGeometry()
width = int(screen_resolution.width())
height = int(screen_resolution.height())
我不知道您使用的是什么代码,所以我没有尝试过。让我知道它是否适合你。
【讨论】:
很遗憾,我感兴趣的是视口大小而不是屏幕分辨率尺寸,但感谢您的回答。以上是关于Plotly 图形组件不能接受视口单位来设置文本注释字体大小的主要内容,如果未能解决你的问题,请参考以下文章
Dash Plotly Graph(Dash 核心组件抛出错误)
python数据可视化(matplotlib,seaborn,plotly)