Добавить горизонтальную дискретную легенду под диаграммой в ggvis

Я хотел бы сделать горизонтальную легенду под диаграммой ggvis. Я могу использовать свойства легенды, чтобы разместить ее под диаграммой, но не знаю, как сделать метки горизонтальными под заголовком легенды. Ниже приведен минимальный воспроизводимый код (взято из Интернета).

df1 = data.frame(x=sample(1:10), y=sample(1:10))
df2 = data.frame(x=1:10, y=1:10)
df3 = data.frame(x=1:10, y=sqrt(1:10))

df2$id <- 1
df3$id <- 2
df4    <- rbind(df2,df3)
df4$id <- factor(df4$id)

df4 %>% ggvis(x=~x, y=~y, stroke=~id) %>% layer_lines() %>%
    # make sure you use add relative scales
    add_relative_scales() %>%
    # values for x and y need to be between 0 and 1
    # e.g for the x-axis 0 is the at far-most left point and 1 at the far-right 
    add_legend("stroke", title="Cylinders",
               properties=legend_props(
                   legend=list(
                       x=scaled_value("x_rel", 0.2),
                       y=scaled_value("y_rel", -.2)
                   ))) %>%
    layer_points(x=~x, y=~y, data=df1, stroke:='black') 

person chungkim271    schedule 26.05.2016    source источник
comment
Поскольку этот вопрос все еще остается открытым на странице разработчика ggvis GitHub, я сомневаюсь, что это возможно без серьезного взлома. Но я могу ошибаться.   -  person Felix    schedule 30.01.2017
comment
@Felix Есть идеи, добавлена ​​ли эта функция в ggvis?   -  person acylam    schedule 05.09.2017
comment
Мой ответ похож на то, что вы ищете?   -  person acylam    schedule 05.09.2017


Ответы (2)


Это, безусловно, хак, но отлично работает:

df4 %>% ggvis(x=~x,y=~y,stroke=~id) %>% layer_lines() %>%
  #make sure you use add relative scales
  add_relative_scales() %>%
  #values for x and y need to be between 0 and 1
  #e.g for the x-axis 0 is the at far-most left point and 1 at the far-right 
  add_legend("stroke", title = "Cylinders", values = c(1, 1),
             properties = legend_props(
               legend = list(
                 x = scaled_value("x_rel", 0.2),
                 y = scaled_value("y_rel", -.2)
               ))) %>%
  add_legend("stroke", title = " ", values = c(2, 2),
             properties = legend_props(
               legend = list(
                 x = scaled_value("x_rel", 0.23),
                 y = scaled_value("y_rel", -.2)
               ))) %>%
  layer_points(x=~x,y=~y,data = df1,stroke:='black') 

введите здесь описание изображения

По сути, я добавляю еще один add_legend, устанавливая заголовок пустым, корректируя scale_value так, чтобы он был очень близок к первой легенде, но не перекрывался. Затем я устанавливаю первую легенду с values = c(1,1), а вторую с values = c(2,2), чтобы два значения складывались друг над другом. Это делает его похожим на одну легенду с горизонтальными значениями.

person acylam    schedule 30.08.2017

Видно, что ggvis сейчас бездействует, возможно, вы можете рассмотреть возможность перехода на googleVis.

Вот аналогичный график, который вы можете получить, немного манипулируя вашими демонстрационными данными:

df5 <- df4[df4$id==1,]
colnames(df5)[2] <- "y1"

library(tidyverse)

df5 <- df5 %>%
  mutate(
    y0 = df1[order(df1$x),c(2)],
    y2 = sqrt(x)
  )

df5 <- df5[, c(1,4,2,5)]

library(googleVis)

plot_df5 <- gvisLineChart(df5, options=list(
                                            legend="bottom",
                                            series =
                                            "[{labelInLegend: 'Dot', color: 'black'},                                            
                                            {labelInLegend: 'Cylinders: 1', color: 'blue', curveType: 'dot'},
                                            {labelInLegend: 'Cylinders: 2', color: 'orange'}]"
                                           )
                         )
plot(plot_df5)

<!-- LineChart generated in R 3.5.2 by googleVis 0.6.2 package -->
<!-- Sun Dec 30 21:21:26 2018 -->


<!-- jsHeader -->
<script type="text/javascript">


// jsData 
function gvisDataLineChartID1fd8710660d () {
var data = new google.visualization.DataTable();
var datajson =
[
 [
"1",
3,
1,
1
],
[
"2",
4,
2,
1.414213562
],
[
"3",
6,
3,
1.732050808
],
[
"4",
1,
4,
2
],
[
"5",
10,
5,
2.236067977
],
[
"6",
8,
6,
2.449489743
],
[
"7",
7,
7,
2.645751311
],
[
"8",
2,
8,
2.828427125
],
[
"9",
9,
9,
3
],
[
"10",
5,
10,
3.16227766
] 
];
data.addColumn('string','x');
data.addColumn('number','y0');
data.addColumn('number','y1');
data.addColumn('number','y2');
data.addRows(datajson);
return(data);
}


// jsDrawChart
function drawChartLineChartID1fd8710660d() {
var data = gvisDataLineChartID1fd8710660d();
var options = {};
options["allowHtml"] = true;
options["legend"] = "bottom";
options["series"] = [{labelInLegend: 'Dot', color: 'black'},                                            
                                            {labelInLegend: 'Cylinders: 1', color: 'blue', curveType: 'dot'},
                                            {labelInLegend: 'Cylinders: 2', color: 'orange'}];


    var chart = new google.visualization.LineChart(
    document.getElementById('LineChartID1fd8710660d')
    );
    chart.draw(data,options);
    

}
  


// jsDisplayChart
(function() {
var pkgs = window.__gvisPackages = window.__gvisPackages || [];
var callbacks = window.__gvisCallbacks = window.__gvisCallbacks || [];
var chartid = "corechart";
  
// Manually see if chartid is in pkgs (not all browsers support Array.indexOf)
var i, newPackage = true;
for (i = 0; newPackage && i < pkgs.length; i++) {
if (pkgs[i] === chartid)
newPackage = false;
}
if (newPackage)
  pkgs.push(chartid);
  
// Add the drawChart function to the global list of callbacks
callbacks.push(drawChartLineChartID1fd8710660d);
})();
function displayChartLineChartID1fd8710660d() {
  var pkgs = window.__gvisPackages = window.__gvisPackages || [];
  var callbacks = window.__gvisCallbacks = window.__gvisCallbacks || [];
  window.clearTimeout(window.__gvisLoad);
  // The timeout is set to 100 because otherwise the container div we are
  // targeting might not be part of the document yet
  window.__gvisLoad = setTimeout(function() {
  var pkgCount = pkgs.length;
  google.load("visualization", "1", { packages:pkgs, callback: function() {
  if (pkgCount != pkgs.length) {
  // Race condition where another setTimeout call snuck in after us; if
  // that call added a package, we must not shift its callback
  return;
}
while (callbacks.length > 0)
callbacks.shift()();
} });
}, 100);
}


// jsFooter
</script>


<!-- jsChart -->  
<script type="text/javascript" src="https://www.google.com/jsapi?callback=displayChartLineChartID1fd8710660d"></script>


<!-- divChart -->
  
<div id="LineChartID1fd8710660d" 
  style="width: 500; height: automatic;">
</div>

person Alessio    schedule 30.12.2018