有没有办法只在R中使用plot_ly制作堆积条形图?我知道可能的解决方案是use ggplot and then convert with ggplotly,但它看起来并不像其他情节图那么好。 Plotly site有一个例子,但是当通过点击图例删除某个类别时,总数保持不变。
制作示例数据:
library(tidyverse)
library(plotly)
# Create some data
grpnames <- c("Thing_3", "Thing_2", "Thing_1")
xval <- as.factor(c(100, 101, 102, 103))
frame <- merge(grpnames, xval, all=T)
yval <- runif(12, 0, .2)
df <- tbl_df(cbind(frame, yval))
colnames(df) <- c("GroupName", "X", "Y")
df.wide <- spread(df, key = GroupName, value = Y)
堆积条块起作用:
# Creates a legit stacked bar where values sum to highest point
plot_ly(df, x = ~X, y = ~Y, color = ~GroupName, type='bar') %>%
layout(barmode = 'stack')
我无法找到类似于&#34; barmode =&#39; stack&#39;&#34;&#34;对于折线图:
# Attempt with tidy data
df %>%
plot_ly(
x = ~X,
y = ~Y,
color = ~GroupName,
type='scatter',
mode = 'lines',
fill = 'tonexty',
fillcolor = ~GroupName)
在这里尝试的Plotly方面的示例并没有为每个X值添加Y的值 - 它只是覆盖它们。
# Attempt with wide data
df.wide %>%
plot_ly(
x = ~X,
y = ~Thing_1,
name = 'Thing 1',
type = 'scatter',
mode = 'none',
fill = 'tozeroy',
fillcolor = 'aquamarine') %>%
add_trace(
x = ~X,
y = ~Thing_2,
name = 'Thing 2',
fill = 'tonexty',
fillcolor = 'orange') %>%
add_trace(
x = ~X,
y = ~Thing_3,
name = 'Thing 3',
fill = 'tonexty',
fillcolor = 'gray')
有没有人能够成功地做到这一点?谢谢!
编辑以供澄清:我知道可以先制作一个cumsum,然后创建图表,但仍然感谢您的回复!我想知道是否可以在图表中进行总和以使其行为类似于堆积条形图,其中单击图例以删除组显示其余组的总和。 < / p>
答案 0 :(得分:3)
您可以调整数据以使用该点的y值的累积和来计算堆积值,例如
library(plotly)
library(tidyverse)
# group, sort (to keep cumulative sum in right order), and adjust Y
df %>% group_by(X) %>% arrange(GroupName) %>% mutate(Y = cumsum(Y)) %>%
plot_ly(type = 'scatter', x = ~X, y = ~Y, color = ~GroupName,
mode = 'lines', fill = 'tonexty')
答案 1 :(得分:0)
您可以通过将要堆叠的内容添加到一起来计算堆叠区域的高度。然后绘制这些已经堆积的累积值。来自原始问题的“可重现的”数据是不可重复的,因此我在这里展示了一些新的数据。
[请注意,在绘图页面上的示例中使用的数据也会转换为这样的累积表 - https://plot.ly/r/filled-area-plots/#stacked-area-chart-with-cumulative-values]
@Theme("mytheme")
public class MyUI extends UI {
@Override
protected void init(VaadinRequest vaadinRequest) {
final VerticalLayout layout = new VerticalLayout();
layout.setMargin(true);
layout.setSpacing(true);
setContent(layout);
BeanItemContainer myBeans = new BeanItemContainer<>(MyBean.class, getBeans());
ComboBox combo = new ComboBox();
combo.setContainerDataSource(myBeans);
combo.setItemCaptionMode(AbstractSelect.ItemCaptionMode.PROPERTY);
combo.setItemCaptionPropertyId("field");
combo.addValueChangeListener(new Property.ValueChangeListener() {
@Override
public void valueChange(Property.ValueChangeEvent event) {
MyBean bean = (MyBean) combo.getValue();
Notification notif = new Notification("Selected Bean Id: "+bean.getId(), Notification.Type.TRAY_NOTIFICATION);
notif.setPosition(Position.TOP_CENTER);
notif.show(Page.getCurrent());
}
});
layout.addComponent(combo);
}
@WebServlet(urlPatterns = "/*", name = "MyUIServlet", asyncSupported = true)
@VaadinServletConfiguration(ui = MyUI.class, productionMode = false)
public static class MyUIServlet extends VaadinServlet {
}
public class MyBean {
private Long id;
private String field;
public MyBean(Long id, String field) {
this.id = id;
this.field = field;
}
public Long getId() {
return id;
}
public String getField() {
return field;
}
}
public ArrayList<MyBean> getBeans() {
ArrayList<MyBean> beans = new ArrayList<>();
MyBean bean = new MyBean(1l, "Vikrant");
beans.add(bean);
bean = new MyBean(2l, "Rampal");
beans.add(bean);
bean = new MyBean(3l, "viky");
beans.add(bean);
return beans;
}
答案 2 :(得分:0)
对于那些在几年后仍然偶然发现这个问题的人(比如我自己):
2021年@kkd42提到的第二个链接还是挺有用的,解决方法是stackgroup='one'
这里。
plot_ly(df,x=~X, y=~Y, color=~GroupName,
type='scatter', mode='line',
stackgroup='one')
为我做这项工作。