如何使一张图表 "span" 成为串联图中多个图表的高度/宽度?
How can I make one chart "span" the height / width of multiple charts in concatenated plots?
在下面的示例中,我想让 exp
填充绘图的整个宽度(因此,与 sin
和 cos
的总和一样宽)。默认情况下,exp
仅填充一列。
我该怎么做,理想情况下使用一些“自动”设置(没有明确地将 width=
设置为数字)?
import altair as alt
import numpy as np
import pandas as pd
x = np.linspace(0, 20, 100)
source = pd.DataFrame({
'x': x,
'sin': np.sin(x),
'cos': np.cos(x),
'exp': np.exp(x),
})
base = alt.Chart(source).mark_line().encode(x='x')
sin = base.encode(y='sin')
cos = base.encode(y='cos')
exp = base.encode(y='exp')
(sin | cos) & exp
据我所知,没有办法自动指定图表的大小来填充多个连接图表的整个布局(但如果你找到一个它可以帮助解决部分 https://github.com/vega/vega-lite/issues/7194 ).
如果您想避免手动估算数字,您可以通过访问每个图表对象的高度并为每个级联添加 60 个像素以编程方式计算高度(我包括了这 60 个中的大部分位置的细分像素来自下面的代码)。这自然不如 "auto"
值方便,但也许至少有点帮助。
不幸的是,这对于宽度来说不是那么简单,因为这取决于最上面一行连接中所有图表的 y-axis 中的位数(最左边的图表除外) , 它将刻度标签扩展到左侧的填充 space 而不会增加图形的总宽度)。
height = (
sin.to_dict()['config']['view']['continuousHeight'] # 300
+ exp.to_dict()['config']['view']['continuousHeight'] # 300
+ 5 # The default bottom padding of chart top-left chart
+ 5 # The default top padding of the bottom-left chart
+ 11 # The default x-axis labels font size (+padding?) of the top-left chart
+ 15 # The default x-axis title font size (+padding?) of the top-left chart
+ 20 # The default spacing between concatenated charts
+ 3 # Not sure where these are from
)
# Notice that the concatenation ordering is different to avoid empty space under the `sin` plot
(sin & exp) | cos.properties(height=height)
宽度的类似解决方案:
w = 200
spacing = 64
base = alt.Chart(source).mark_line().encode(x='x')
sin = base.encode(y='sin').properties(width=w, height=100)
cos = base.encode(y='cos').properties(width=w, height=100)
exp = base.encode(y='exp').properties(width=2*w+spacing, height=100)
row = alt.hconcat(sin, cos).properties(
bounds='flush',
spacing=spacing
)
alt.vconcat(row, exp).configure_axisY(labelLimit=spacing)
未对齐,但使用更少的代码可能在视觉上足够好:
w = 200
base = alt.Chart(source).mark_line().encode(x='x')
sin = base.encode(y='sin').properties(width=w, height=100)
cos = base.encode(y='cos').properties(width=w, height=100)
exp = base.encode(y='exp').properties(width=2*w, height=100)
row = alt.hconcat(sin, cos)
alt.vconcat(row, exp).properties(center=True)
在下面的示例中,我想让 exp
填充绘图的整个宽度(因此,与 sin
和 cos
的总和一样宽)。默认情况下,exp
仅填充一列。
我该怎么做,理想情况下使用一些“自动”设置(没有明确地将 width=
设置为数字)?
import altair as alt
import numpy as np
import pandas as pd
x = np.linspace(0, 20, 100)
source = pd.DataFrame({
'x': x,
'sin': np.sin(x),
'cos': np.cos(x),
'exp': np.exp(x),
})
base = alt.Chart(source).mark_line().encode(x='x')
sin = base.encode(y='sin')
cos = base.encode(y='cos')
exp = base.encode(y='exp')
(sin | cos) & exp
据我所知,没有办法自动指定图表的大小来填充多个连接图表的整个布局(但如果你找到一个它可以帮助解决部分 https://github.com/vega/vega-lite/issues/7194 ).
如果您想避免手动估算数字,您可以通过访问每个图表对象的高度并为每个级联添加 60 个像素以编程方式计算高度(我包括了这 60 个中的大部分位置的细分像素来自下面的代码)。这自然不如 "auto"
值方便,但也许至少有点帮助。
不幸的是,这对于宽度来说不是那么简单,因为这取决于最上面一行连接中所有图表的 y-axis 中的位数(最左边的图表除外) , 它将刻度标签扩展到左侧的填充 space 而不会增加图形的总宽度)。
height = (
sin.to_dict()['config']['view']['continuousHeight'] # 300
+ exp.to_dict()['config']['view']['continuousHeight'] # 300
+ 5 # The default bottom padding of chart top-left chart
+ 5 # The default top padding of the bottom-left chart
+ 11 # The default x-axis labels font size (+padding?) of the top-left chart
+ 15 # The default x-axis title font size (+padding?) of the top-left chart
+ 20 # The default spacing between concatenated charts
+ 3 # Not sure where these are from
)
# Notice that the concatenation ordering is different to avoid empty space under the `sin` plot
(sin & exp) | cos.properties(height=height)
宽度的类似解决方案:
w = 200
spacing = 64
base = alt.Chart(source).mark_line().encode(x='x')
sin = base.encode(y='sin').properties(width=w, height=100)
cos = base.encode(y='cos').properties(width=w, height=100)
exp = base.encode(y='exp').properties(width=2*w+spacing, height=100)
row = alt.hconcat(sin, cos).properties(
bounds='flush',
spacing=spacing
)
alt.vconcat(row, exp).configure_axisY(labelLimit=spacing)
未对齐,但使用更少的代码可能在视觉上足够好:
w = 200
base = alt.Chart(source).mark_line().encode(x='x')
sin = base.encode(y='sin').properties(width=w, height=100)
cos = base.encode(y='cos').properties(width=w, height=100)
exp = base.encode(y='exp').properties(width=2*w, height=100)
row = alt.hconcat(sin, cos)
alt.vconcat(row, exp).properties(center=True)