【问题标题】:How can I color dots in a xy scatterplot according to column value?如何根据列值对 xy 散点图中的点进行着色?
【发布时间】:2013-06-16 03:45:43
【问题描述】:

考虑以下工作表:

     A       B        C        D
1 COMPANY  XVALUE   YVALUE   GROUP
2 Apple     45       35       red
3 Xerox     45       38       red
4 KMart     63       50       orange
5 Exxon     53       59       green

我已经使用 Excel 中的散点图功能创建了以下图表:

但是,图表中的每个点都有一个附加属性:GROUP。有四个组:redorangeblackgreen。我想相应地为每个点着色,以便我可以看到一个模式(例如,green 组几乎总是在图表的左侧)。因为我的列表有 500 行长,所以我无法手动执行此操作。如何自动执行此操作?

【问题讨论】:

  • 你可以尝试适应这种技术:peltiertech.com/WordPress/…
  • 正在对组列进行排序,然后制作 4 个图(每组 1 个)没有问题?
  • @chancea 我需要所有点都出现在同一个图中,如上所述,而不是在 4 个不同的图中。如果您的解决方案需要 4 倍的工作量,但所有点都出现在同一个图中,那就太好了。这对你的问题有帮助吗?
  • 是的,4 个图我的意思是 1 个图中的 4 个数据集。它们将重叠在彼此之上。按组对列进行排序将允许您手动选择数据集,但如果您曾经将数据添加到电子表格中,它不会帮助您。我在下面的回答解释了一种更自动化的方式,当我说地块时,我指的是Select Data Source -> Add
  • 这是一个非常有限的解决方案,设计也很糟糕,因为它在可能位于不同工作表上的数据排序与图表之间产生了不可见的紧密耦合。此外,如果不破坏情节,就无法对其他视图的数据进行排序,正如刚才所说,甚至可能不知道。

标签: vba excel charts excel-formula


【解决方案1】:

非 VBA 解决方案:

您需要为每个颜色组创建一组额外的数据,以表示该特定组的 Y 值。您可以使用这些组在图表中创建多个数据集。

这是一个使用您的数据的示例:

     A       B        C        D                    E                        F                            G
----------------------------------------------------------------------------------------------------------------------
1| COMPANY  XVALUE   YVALUE   GROUP                 Red                     Orange                       Green
2| Apple     45       35       red         =IF($D2="red",$C2,NA()) =IF($D2="orange",$C2,NA()) =IF($D2="green",$C2,NA())
3| Xerox     45       38       red         =IF($D3="red",$C3,NA()) =IF($D3="orange",$C3,NA()) =IF($D3="green",$C3,NA())
4| KMart     63       50       orange      =IF($D4="red",$C4,NA()) =IF($D4="orange",$C4,NA()) =IF($D4="green",$C4,NA())
5| Exxon     53       59       green       =IF($D5="red",$C5,NA()) =IF($D5="orange",$C5,NA()) =IF($D5="green",$C5,NA())

之后应该是这样的:

     A       B        C        D          E           F          G
---------------------------------------------------------------------
1| COMPANY  XVALUE   YVALUE   GROUP       Red         Orange     Green
2| Apple     45       35       red         35         #N/A       #N/A    
3| Xerox     45       38       red         38         #N/A       #N/A
4| KMart     63       50       orange     #N/A         50        #N/A
5| Exxon     53       59       green      #N/a        #N/A        59

现在您可以使用不同的数据集生成图表。这是一张仅显示此示例数据的图片:

您可以将系列(X;Y) 的值分别更改为B:B ; E:EB:B ; F:FB:B ; G:G,以便在添加更多数据时自动更新图表。

【讨论】:

  • 你真的不需要对 X 值做任何事情。所有四个系列的颜色都可以共享 B 列的 X 值。使用上面 G 列中使用的公式方法生成红色的 Y 值,但对其他三种颜色重复。
  • 将单元格 E2 中的公式更改为 =IF($D2=E$1,$C2,NA()),然后您可以为所有组(E、F 和 G 列)复制/粘贴相同的公式。
【解决方案2】:

我回答了一个非常相似的问题:

https://stackoverflow.com/a/15982217/1467082

您只需遍历系列的.Points 集合,然后您可以根据您需要的任何标准分配点的.Format.Fill.ForeColor.RGB 值。

更新

下面的代码将根据屏幕截图为图表着色。这仅假设使用了三种颜色。您可以为其他颜色值添加额外的 case 语句,并将 myColor 的分配更新为每个颜色值的适当 RGB 值。

Option Explicit
Sub ColorScatterPoints()
    Dim cht As Chart
    Dim srs As Series
    Dim pt As Point
    Dim p As Long
    Dim Vals$, lTrim#, rTrim#
    Dim valRange As Range, cl As Range
    Dim myColor As Long

    Set cht = ActiveSheet.ChartObjects(1).Chart
    Set srs = cht.SeriesCollection(1)

   '## Get the series Y-Values range address:
    lTrim = InStrRev(srs.Formula, ",", InStrRev(srs.Formula, ",") - 1, vbBinaryCompare) + 1
    rTrim = InStrRev(srs.Formula, ",")
    Vals = Mid(srs.Formula, lTrim, rTrim - lTrim)
    Set valRange = Range(Vals)

    For p = 1 To srs.Points.Count
        Set pt = srs.Points(p)
        Set cl = valRange(p).Offset(0, 1) '## assume color is in the next column.

        With pt.Format.Fill
            .Visible = msoTrue
            '.Solid  'I commented this out, but you can un-comment and it should still work
            '## Assign Long color value based on the cell value
            '## Add additional cases as needed.
            Select Case LCase(cl)
                Case "red"
                    myColor = RGB(255, 0, 0)
                Case "orange"
                    myColor = RGB(255, 192, 0)
                Case "green"
                    myColor = RGB(0, 255, 0)
            End Select

            .ForeColor.RGB = myColor

        End With
    Next


End Sub

【讨论】:

  • 谢谢!但是,您能否向我解释一下如何根据GROUP 列中的值动态更改颜色?我在您的帖子中添加了伪代码,但不知道如何将点 p 实际连接到正确的 GROUP 值...
  • 我没有看到对 my 帖子的任何修改,在任何情况下,请不要修改某人回答的内容,除非是为了纠正明显的错误或格式/可读性。切勿永远在其他人的帖子/答案中添加内容。我会暂时修改我的答案,使其更适合您的具体问题。
  • 一定有人在你看到之前拒绝了我所做的修改。无论如何,我认为编辑按钮也可以进行添加,而不是进行另一条评论。现在我知道了 :-) 感谢您的帮助,它就像一个魅力!
  • 我确实看到三个人拒绝了它(因为它是对现有答案的评论或回复,而不是因其本身的优点而进行的建设性编辑)。不过不用担心。很高兴它对你有用!
  • 工作就像一个魅力!
【解决方案3】:

试试这个:

Dim xrndom As Random
    Dim x As Integer
    xrndom = New Random

    Dim yrndom As Random
    Dim y As Integer
    yrndom = New Random
    'chart creation
    Chart1.Series.Add("a")
    Chart1.Series("a").ChartType = DataVisualization.Charting.SeriesChartType.Point
    Chart1.Series("a").MarkerSize = 10
    Chart1.Series.Add("b")
    Chart1.Series("b").ChartType = DataVisualization.Charting.SeriesChartType.Point
    Chart1.Series("b").MarkerSize = 10
    Chart1.Series.Add("c")
    Chart1.Series("c").ChartType = DataVisualization.Charting.SeriesChartType.Point
    Chart1.Series("c").MarkerSize = 10
    Chart1.Series.Add("d")
    Chart1.Series("d").ChartType = DataVisualization.Charting.SeriesChartType.Point
    Chart1.Series("d").MarkerSize = 10
    'color
    Chart1.Series("a").Color = Color.Red
    Chart1.Series("b").Color = Color.Orange
    Chart1.Series("c").Color = Color.Black
    Chart1.Series("d").Color = Color.Green
    Chart1.Series("Chart 1").Color = Color.Blue

    For j = 0 To 70
        x = xrndom.Next(0, 70)
        y = xrndom.Next(0, 70)
        'Conditions
        If j < 10 Then
            Chart1.Series("a").Points.AddXY(x, y)
        ElseIf j < 30 Then
            Chart1.Series("b").Points.AddXY(x, y)
        ElseIf j < 50 Then
            Chart1.Series("c").Points.AddXY(x, y)
        ElseIf 50 < j Then
            Chart1.Series("d").Points.AddXY(x, y)
        Else
            Chart1.Series("Chart 1").Points.AddXY(x, y)
        End If
    Next

【讨论】:

    【解决方案4】:

    最近我不得不做一些类似的事情,我用下面的代码解决了它。希望对您有所帮助!

    Sub ColorCode()
    Dim i As Integer
    Dim j As Integer
    i = 2
    j = 1
    
    Do While ActiveSheet.Cells(i, 1) <> ""
    
    
    If Cells(i, 5).Value = "RED" Then
    ActiveSheet.ChartObjects("YourChartName").Chart.FullSeriesCollection(1).Points(j).MarkerForegroundColor = RGB(255, 0, 0)
    
    
    
    Else
    
    If Cells(i, 5).Value = "GREEN" Then
    ActiveSheet.ChartObjects("YourChartName").Chart.FullSeriesCollection(1).Points(j).MarkerForegroundColor = RGB(0, 255, 0)
    
    Else
    
    If Cells(i, 5).Value = "GREY" Then
    ActiveSheet.ChartObjects("YourChartName").Chart.FullSeriesCollection(1).Points(j).MarkerForegroundColor = RGB(192, 192, 192)
    
    Else
    
    If Cells(i, 5).Value = "YELLOW" Then
    ActiveSheet.ChartObjects("YourChartName").Chart.FullSeriesCollection(1).Points(j).MarkerForegroundColor = RGB(255, 255, 0)
    
    End If
    End If
    End If
    End If
    
    i = i + 1
    j = j + 1
    
    Loop
    
    
    
    End Sub
    

    【讨论】:

    • 欢迎来到 StackOverflow。请用您的代码发布 cmets,以便人们了解它的工作原理。
    【解决方案5】:

    我看到有 VBA 解决方案和非 VBA 解决方案,两者都非常好。我想提出我的 Javascript 解决方案

    有一个名为Funfun 的 Excel 加载项允许您在 Excel 中使用 javascript、HTML 和 css。它有一个带有嵌入式电子表格的在线编辑器,您可以在其中构建图表。

    我用Chart.js为你写了这段代码:

    https://www.funfun.io/1/#/edit/5a61ed15404f66229bda3f44

    为了创建这个图表,我在电子表格中输入了我的数据并使用 json 文件读取它,它是 short 文件。

    我确保以正确的格式将其放入script.js,以便将其添加到我的图表中:

    var data = [];
    var color = [];
    var label = [];
    
    for (var i = 1; i < $internal.data.length; i++)
    {
        label.push($internal.data[i][0]);
        data.push([$internal.data[i][1], $internal.data[i][2]]);
        color.push($internal.data[i][3]);
    }
    

    然后我创建散点图,每个点都有指定的颜色和位置:

     var dataset = [];
      for (var i = 0; i < data.length; i++) {   
        dataset.push({
          data: [{
            x: data[i][0],
            y: data[i][1] 
          }],
          pointBackgroundColor: color[i],
          pointStyle: "cercle",
          radius: 6  
        });
      }
    

    创建散点图后,我可以通过将 URL 粘贴到 funfun Excel add-in 中将其上传到 Excel 中。以下是我的示例:

    完成此操作后,您可以在 Excel 中通过更改电子表格中的值立即更改点的颜色或位置。

    如果要在图表中添加额外的点,只需在short json 文件中修改data 的半径即可。

    希望这个 Javascript 解决方案能有所帮助!

    披露:我是 funfun 的开发者

    【讨论】:

      【解决方案6】:

      如果您对 x 轴文本类别进行编码,将它们列在单列中,然后在相邻列中针对相关文本类别代码列出各个变量的绘图点,并针对不相关的文本类别代码留下空白单元格,您可以分散绘制并获得显示的结果。任何问题让我知道。

      【讨论】:

        猜你喜欢
        • 2012-08-06
        • 1970-01-01
        • 1970-01-01
        • 2021-10-05
        • 2017-07-25
        • 1970-01-01
        • 1970-01-01
        • 2018-09-22
        • 1970-01-01
        相关资源
        最近更新 更多