堆积面积图使用Plotly和R没有ggplot

时间:2017-01-28 01:40:04

标签: r plotly

有没有办法只在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>

3 个答案:

答案 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')

stacked plotly area plot

答案 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;
}

enter image description here

答案 2 :(得分:0)

对于那些在几年后仍然偶然发现这个问题的人(比如我自己):

2021年@kkd42提到的第二个链接还是挺有用的,解决方法是stackgroup='one'这里。

plot_ly(df,x=~X, y=~Y, color=~GroupName,
       type='scatter', mode='line', 
       stackgroup='one')

为我做这项工作。