我正在尝试使用Python中的Altair来制作条形图,条形图中的条形图的宽度取决于源数据帧的列中的数据。最终的目标是得到一个这样的图表:

条形的高度对应于每种能源技术的边际成本(作为源数据帧中的一列给出)。条形宽度对应于每种能源技术的容量(也作为源数据帧中的列给出)。颜色也是来自源数据帧的顺序数据。条形图按照边际成本递增的顺序进行排序。(在能源行业中,这样的情节被称为“发电堆栈”)。这在matplotlib中很容易实现,如以下代码所示:
import matplotlib.pyplot as plt
# Make fake dataset
height = [3, 12, 5, 18, 45]
bars = ('A', 'B', 'C', 'D', 'E')
# Choose the width of each bar and their positions
width = [0.1,0.2,3,1.5,0.3]
y_pos = [0,0.3,2,4.5,5.5]
# Make the plot
plt.bar(y_pos, height, width=width)
plt.xticks(y_pos, bars)
plt.show()(代码来自https://python-graph-gallery.com/5-control-width-and-space-in-barplots/)
但是有没有办法用牵牛星做到这一点呢?我想用Altair这样做,这样我仍然可以获得Altair的其他很好的功能,比如工具提示,选择器/绑定,因为我有很多其他数据想要显示在条形图旁边。
我的源数据的前20行如下所示:

(与上面显示的图表不完全匹配)。
发布于 2020-01-06 22:58:34
在牛郎星中,做到这一点的方法是使用rect标记并显式地构造条形图。下面是一个模拟您的数据的示例:
import altair as alt
import pandas as pd
import numpy as np
np.random.seed(0)
df = pd.DataFrame({
'MarginalCost': 100 * np.random.rand(30),
'Capacity': 10 * np.random.rand(30),
'Technology': np.random.choice(['SOLAR', 'THERMAL', 'WIND', 'GAS'], 30)
})
df = df.sort_values('MarginalCost')
df['x1'] = df['Capacity'].cumsum()
df['x0'] = df['x1'].shift(fill_value=0)
alt.Chart(df).mark_rect().encode(
x=alt.X('x0:Q', title='Capacity'),
x2='x1',
y=alt.Y('MarginalCost:Q', title='Marginal Cost'),
color='Technology:N',
tooltip=["Technology", "Capacity", "MarginalCost"]
)

要在不对数据进行预处理的情况下获得相同的结果,可以使用Altair的transform语法:
df = pd.DataFrame({
'MarginalCost': 100 * np.random.rand(30),
'Capacity': 10 * np.random.rand(30),
'Technology': np.random.choice(['SOLAR', 'THERMAL', 'WIND', 'GAS'], 30)
})
alt.Chart(df).transform_window(
x1='sum(Capacity)',
sort=[alt.SortField('MarginalCost')]
).transform_calculate(
x0='datum.x1 - datum.Capacity'
).mark_rect().encode(
x=alt.X('x0:Q', title='Capacity'),
x2='x1',
y=alt.Y('MarginalCost:Q', title='Marginal Cost'),
color='Technology:N',
tooltip=["Technology", "Capacity", "MarginalCost"]
)https://stackoverflow.com/questions/59608560
复制相似问题