简体   繁体   English

plotly 漏斗图是否可以有阴影颜色?

[英]Is it possible to have hatched colours for a plotly funnel chart?

I am trying the following code but am not getting any hatched bars:我正在尝试以下代码,但没有得到任何阴影条:

plot_ly() %>% 
  add_trace(type="funnel",
  y = c("level one","level two"),
  x = c(500,100),
  marker = list(pattern = list(shape = "X")))

I couldn't find a way through Plotly, but I did find a way around it.我找不到通过Plotly 的方法,但我确实找到了解决方法。 Essentially, you have two options.本质上,您有两个选择。 You can create and call the pattern definitions.您可以创建和调用模式定义。 Or you exploit Plotly and repurpose their work.或者你利用 Plotly 并重新利用他们的工作。 Since I'm all about working smarter, not harder...因为我只想更聪明地工作,而不是更努力地工作......

I planned on making a funnel with a depth of five layers with a plot pilfered from Plotly's examples.我计划用从 Plotly 的示例中窃取的 plot 制作一个深度为五层的漏斗。 So to create the patterns, I created a 5-bar barplot with patterns.因此,为了创建模式,我创建了一个带有模式的 5 条柱状图。 (I actually used the funnel data in the bar plot, but the data is irrelevant.) (其实我用的是plot栏里的漏斗数据,但是数据是无关紧要的。)

The important part is designating the patterns that you want to see in the funnel plot.重要的部分是指定您希望在漏斗 plot 中看到的模式。

library(plotly)

xy = data.frame(x = c("Website visit", "Downloads", "Potential customers", 
                      "Requested price", "invoice sent"),
                y = c(39, 27.4, 20.6, 11, 2))

plot_ly(type = "bar", data = xy, x = ~x, y = ~y,
        marker = list(pattern = list(
          fillmode = "overlay", 
          shape = setNames(c("/", "x", "-", "+", "."), 
                           unlist(xy$x)))))

在此处输入图像描述

I opened the plot in my browser and copied the entire <g class="patterns"> element.我在浏览器中打开了 plot 并复制了整个<g class="patterns">元素。

Open the plot in the browser.在浏览器中打开 plot。 Then right-click on the browser, select 'inspect' or 'developer tools'.然后右键单击浏览器,select“检查”或“开发者工具”。 (The verbiage depends on your browser.) Go to the elements tab and look for SVG -> defs. (措辞取决于您的浏览器。) Go 到元素选项卡并查找 SVG -> defs。

在此处输入图像描述

Click on the ellipses on the left side of the screen, then select copy element .单击屏幕左侧的省略号,然后单击 select copy element In the next step, I'm going to change the IDs.在下一步中,我将更改 ID。 You may find it a lot easier to change them in HTML before you copy them.在复制它们之前,您可能会发现在 HTML 中更改它们要容易得多。

# copied patterns from this plot
ptn <- '<g class="patterns"><pattern id="p3fa9fb-687849-0" width="11.313708498984761px" height="11.313708498984761px" patternUnits="userSpaceOnUse" patternTransform=""><rect width="11.313708498984761px" height="11.313708498984761px" fill="rgba(31,119,180,1)"></rect><path d="M-2.8284271247461903,2.8284271247461903l5.656854249492381,-5.656854249492381M0,11.313708498984761L11.313708498984761,0M8.485281374238571,14.142135623730951l5.656854249492381,-5.656854249492381" opacity="0.5" stroke="#fff" stroke-width="2.4px"></path></pattern><pattern id="p3fa9fb-687849-1" width="11.313708498984761px" height="11.313708498984761px" patternUnits="userSpaceOnUse" patternTransform=""><rect width="11.313708498984761px" height="11.313708498984761px" fill="rgba(31,119,180,1)"></rect><path d="M-2.8284271247461903,2.8284271247461903l5.656854249492381,-5.656854249492381M0,11.313708498984761L11.313708498984761,0M8.485281374238571,14.142135623730951l5.656854249492381,-5.656854249492381M8.485281374238571,-2.8284271247461903l5.656854249492381,5.656854249492381M0,0L11.313708498984761,11.313708498984761M-2.8284271247461903,8.485281374238571l5.656854249492381,5.656854249492381" opacity="0.5" stroke="#fff" stroke-width="1.3067197877273955px"></path></pattern><pattern id="p3fa9fb-687849-2" width="8px" height="8px" patternUnits="userSpaceOnUse" patternTransform=""><rect width="8px" height="8px" fill="rgba(31,119,180,1)"></rect><path d="M0,4L8,4" opacity="0.5" stroke="#fff" stroke-width="2.4px"></path></pattern><pattern id="p3fa9fb-687849-3" width="8px" height="8px" patternUnits="userSpaceOnUse" patternTransform=""><rect width="8px" height="8px" fill="rgba(31,119,180,1)"></rect><path d="M4,0L4,8M0,4L8,4" opacity="0.5" stroke="#fff" stroke-width="1.3067197877273955px"></path></pattern><pattern id="p3fa9fb-687849-4" width="8px" height="8px" patternUnits="userSpaceOnUse" patternTransform=""><rect width="8px" height="8px" fill="rgba(31,119,180,1)"></rect><circle cx="4" cy="4" r="2.472154892948413" opacity="0.5" fill="#fff"></circle></pattern></g>'
      # changed the ids to p-slash, p-ex, p-dash, p-plus, and p-dot
ptn2 <- '<g class="patterns"><pattern id="p-slash" width="11.313708498984761px" height="11.313708498984761px" patternUnits="userSpaceOnUse" patternTransform=""><rect width="11.313708498984761px" height="11.313708498984761px" fill="rgba(31,119,180,1)"></rect><path d="M-2.8284271247461903,2.8284271247461903l5.656854249492381,-5.656854249492381M0,11.313708498984761L11.313708498984761,0M8.485281374238571,14.142135623730951l5.656854249492381,-5.656854249492381" opacity="0.5" stroke="#fff" stroke-width="2.4px"></path></pattern><pattern id="p-ex" width="11.313708498984761px" height="11.313708498984761px" patternUnits="userSpaceOnUse" patternTransform=""><rect width="11.313708498984761px" height="11.313708498984761px" fill="rgba(31,119,180,1)"></rect><path d="M-2.8284271247461903,2.8284271247461903l5.656854249492381,-5.656854249492381M0,11.313708498984761L11.313708498984761,0M8.485281374238571,14.142135623730951l5.656854249492381,-5.656854249492381M8.485281374238571,-2.8284271247461903l5.656854249492381,5.656854249492381M0,0L11.313708498984761,11.313708498984761M-2.8284271247461903,8.485281374238571l5.656854249492381,5.656854249492381" opacity="0.5" stroke="#fff" stroke-width="1.3067197877273955px"></path></pattern><pattern id="p-dash" width="8px" height="8px" patternUnits="userSpaceOnUse" patternTransform=""><rect width="8px" height="8px" fill="rgba(31,119,180,1)"></rect><path d="M0,4L8,4" opacity="0.5" stroke="#fff" stroke-width="2.4px"></path></pattern><pattern id="p-plus" width="8px" height="8px" patternUnits="userSpaceOnUse" patternTransform=""><rect width="8px" height="8px" fill="rgba(31,119,180,1)"></rect><path d="M4,0L4,8M0,4L8,4" opacity="0.5" stroke="#fff" stroke-width="1.3067197877273955px"></path></pattern><pattern id="p-dot" width="8px" height="8px" patternUnits="userSpaceOnUse" patternTransform=""><rect width="8px" height="8px" fill="rgba(31,119,180,1)"></rect><circle cx="4" cy="4" r="2.472154892948413" opacity="0.5" fill="#fff"></circle></pattern></g>'

If you wanted to change them in HTML (which is probably easier), double-click on the string next to the attribute "id".如果您想在 HTML 中更改它们(这可能更容易),请双击属性“id”旁边的字符串。 If something goes wrong, just refresh your browser, no harm done.如果出现问题,只需刷新浏览器即可,不会造成任何伤害。 I made them names that were definitely not keywords in HTML, CSS, or JS, and identified what they represented: p-slash , p-ex , p-dash , p-plus , and p-dot .我将它们命名为 HTML、CSS 或 JS 中绝对不是关键字的名称,并确定它们代表的内容: p-slashp-exp-dashp-plusp-dot

在此处输入图像描述

在此处输入图像描述

Now you just have to take this content and feed it back to Plotly...well, shove it down its throat, really.现在你只需要把这个内容反馈给 Plotly ......好吧,把它塞进喉咙里,真的。

This uses the library htmlwidgets .这使用库htmlwidgets Since it's only used this one time, I didn't call the library.因为只用过这一次,所以没有给图书馆打电话。

This call for onRender looks for the defs of your funnel plot (which will be empty), and replaces it.这个onRender调用会查找您的漏斗 plot(将为空)的defs ,并替换它。 Then it looks for each layer of the funnel and changes the fill from a color to one of these patterns pilfered from the barplot.然后它查找漏斗的每一层,并将填充从一种颜色更改为从条形图中窃取的这些图案之一。

One tip...don't forget (or by the way, if you didn't know) Javascript indices start at zero, unlike R which starts everything at 1. So the first layer is layer zero.一个提示......不要忘记(或者顺便说一句,如果你不知道)Javascript 索引从零开始,这与 R 不同,它从 1 开始。所以第一层是第零层。

When you execute the declarations of ptn or ptn2 in R, it will automatically add the "" before each " . So call it and then copy the string in the console when you add it to the onRender function in this code.当你在 R 中执行ptnptn2的声明时,它会自动在每个 " 之前添加 " " 。所以调用它,然后在将它添加到此代码中的onRender function 时在控制台中复制字符串。

plot_ly(type = "funnel",        # make the finicky funnel
        y = c("Website visit", "Downloads", "Potential customers", 
              "Requested price", "invoice sent"), 
        x = c(39, 27.4, 20.6, 11, 2)) %>%
  layout(yaxis = list(categoryarray = unlist(xy$y))) %>% 
  htmlwidgets::onRender("setTimeout(function() {  /* find and replace patterns */
                          ptn = document.querySelector('svg > defs > g.patterns');
                          ptn.outerHTML = '<g class=\"patterns\"><pattern id=\"p-slash\" width=\"11.313708498984761px\" height=\"11.313708498984761px\" patternUnits=\"userSpaceOnUse\" patternTransform=\"\"><rect width=\"11.313708498984761px\" height=\"11.313708498984761px\" fill=\"rgba(31,119,180,1)\"></rect><path d=\"M-2.8284271247461903,2.8284271247461903l5.656854249492381,-5.656854249492381M0,11.313708498984761L11.313708498984761,0M8.485281374238571,14.142135623730951l5.656854249492381,-5.656854249492381\" opacity=\"0.5\" stroke=\"#fff\" stroke-width=\"2.4px\"></path></pattern><pattern id=\"p-ex\" width=\"11.313708498984761px\" height=\"11.313708498984761px\" patternUnits=\"userSpaceOnUse\" patternTransform=\"\"><rect width=\"11.313708498984761px\" height=\"11.313708498984761px\" fill=\"rgba(31,119,180,1)\"></rect><path d=\"M-2.8284271247461903,2.8284271247461903l5.656854249492381,-5.656854249492381M0,11.313708498984761L11.313708498984761,0M8.485281374238571,14.142135623730951l5.656854249492381,-5.656854249492381M8.485281374238571,-2.8284271247461903l5.656854249492381,5.656854249492381M0,0L11.313708498984761,11.313708498984761M-2.8284271247461903,8.485281374238571l5.656854249492381,5.656854249492381\" opacity=\"0.5\" stroke=\"#fff\" stroke-width=\"1.3067197877273955px\"></path></pattern><pattern id=\"p-dash\" width=\"8px\" height=\"8px\" patternUnits=\"userSpaceOnUse\" patternTransform=\"\"><rect width=\"8px\" height=\"8px\" fill=\"rgba(31,119,180,1)\"></rect><path d=\"M0,4L8,4\" opacity=\"0.5\" stroke=\"#fff\" stroke-width=\"2.4px\"></path></pattern><pattern id=\"p-plus\" width=\"8px\" height=\"8px\" patternUnits=\"userSpaceOnUse\" patternTransform=\"\"><rect width=\"8px\" height=\"8px\" fill=\"rgba(31,119,180,1)\"></rect><path d=\"M4,0L4,8M0,4L8,4\" opacity=\"0.5\" stroke=\"#fff\" stroke-width=\"1.3067197877273955px\"></path></pattern><pattern id=\"p-dot\" width=\"8px\" height=\"8px\" patternUnits=\"userSpaceOnUse\" patternTransform=\"\"><rect width=\"8px\" height=\"8px\" fill=\"rgba(31,119,180,1)\"></rect><circle cx=\"4\" cy=\"4\" r=\"2.472154892948413\" opacity=\"0.5\" fill=\"#fff\"></circle></pattern></g>';
                                          /* find the plot layers */
                          lyrs = document.querySelectorAll('svg g.cartesianlayer g.plot g.point');
                                          /* define the patterns for each layer */
                          lyrs[0].firstChild.style.fill = 'url(#p-slash)';
                          lyrs[1].firstChild.style.fill = 'url(#p-ex)';
                          lyrs[2].firstChild.style.fill = 'url(#p-dash)';
                          lyrs[3].firstChild.style.fill = 'url(#p-plus)';
                          lyrs[4].firstChild.style.fill = 'url(#p-dot)';
                        },200)")

在此处输入图像描述

If you have any questions, let me know.如果您有任何问题,请告诉我。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM