Disponemos de dos casos, en ambos creamos un gráfico de dispersión XY con puntos constituidos por parejas de datos aleatorios. En el primer caso los datos se encuentran en la propia hoja de cálculo y en segundo caso los datos se generan de forma aleatoria en la propia macro, usando simplemente código VBA.
Hoja1
La capacidad de representar datos en un gráfico está limitada en Excel según la versión. Seguidamente se muestran las limitaciones de la versión 2016.
La información anterior está obtenida de la página de Microsoft. En la Hoja1 hemos creado 30.000 parejas de valores.
En las columnas A y B creamos aleatoriamente el radio y el ángulo que son las dos coordenadas polares que vamos a manejar. Luego en las columnas C y D convertimos las coordenadas polares en coordenadas cartesianas con la fórmula siguiente.
Si el radio se obtiene con la función aleatorio() esto nos permite crear un gráfico como el siguiente.
Observamos una mayor concentración de puntos en el centro. Si queremos que la distribución de puntos aleatorios sea uniforme en toda la circunferencia hemos de elegir el radio como la raiz cuadrada de una uniforme cero uno.
Con este cambio obtendremos el siguiente gráfico que podemos ver en forma de gif animado obtenido al recalcular los valores aleatorios pulsando la tecla de función F9 de forma reiterada.
En las columnas A y B creamos aleatoriamente el radio y el ángulo que son las dos coordenadas polares que vamos a manejar. Luego en las columnas C y D convertimos las coordenadas polares en coordenadas cartesianas con la fórmula siguiente.
Si el radio se obtiene con la función aleatorio() esto nos permite crear un gráfico como el siguiente.
Observamos una mayor concentración de puntos en el centro. Si queremos que la distribución de puntos aleatorios sea uniforme en toda la circunferencia hemos de elegir el radio como la raiz cuadrada de una uniforme cero uno.
=raiz(aleatorio())
Con este cambio obtendremos el siguiente gráfico que podemos ver en forma de gif animado obtenido al recalcular los valores aleatorios pulsando la tecla de función F9 de forma reiterada.
Hoja2
Con el segundo caso veremos cómo generar los puntos aleatorios con una macro. Mediante código VBA crearemos una matriz para el eje X y otra matriz para el eje Y. Luego introduciremos ambas matrices como las series de valores para poder generar el gráfico de tipo dispersión XY.Primera macro
Sub generaChartConArray1()
Dim A(16000) As Variant
Dim B(16000) As Variant
Dim i As Long
Dim grafico As ChartObject
Dim c As Byte
Dim ChtObj As ChartObject
Worksheets("Hoja2").Activate
c = 0
Randomize
For i = 1 To 16000
A(i) = Rnd
B(i) = Rnd
Next i
For Each grafico In Worksheets("Hoja2").ChartObjects
If grafico.Name = "migas" Then
c = c + 1
End If
Next
If c = 0 Then
Set ChtObj = Worksheets("Hoja2").ChartObjects.Add(Left:=10, Top:=10, _
Width:=400, Height:=400)
With ChtObj
.Chart.ChartType = xlXYScatter
.Chart.SetSourceData Source:=Range("Hoja2!$A$1:$B$2")
.Name = "migas"
End With
End If
ActiveSheet.ChartObjects("migas").Activate
ActiveChart.SeriesCollection(1).XValues = A
ActiveChart.SeriesCollection(1).Values = B
ActiveChart.Axes(xlCategory).MaximumScale = 1
ActiveChart.Axes(xlCategory).MinimumScale = 0
ActiveChart.Axes(xlValue).MaximumScale = 1
ActiveChart.Axes(xlValue).MinimumScale = 0
ActiveChart.SetElement (msoElementLegendNone)
ActiveChart.SetElement (msoElementPrimaryValueGridLinesNone)
ActiveChart.SetElement (msoElementPrimaryCategoryAxisNone)
ActiveChart.SetElement (msoElementPrimaryValueAxisNone)
ActiveChart.SetElement (msoElementChartTitleNone)
ActiveChart.FullSeriesCollection(1).MarkerStyle = -4118
ActiveChart.FullSeriesCollection(1).MarkerSize = 2
Range("A1").Select
End Sub
Segunda macro
Sub generaChartConArray2()
Dim A() As Variant
Dim B() As Variant
Dim i As Long
Dim radio As Double
Dim angulo As Double
Dim grafico As ChartObject
Dim c As Byte
Dim n As Long
Dim ChtObj As ChartObject
Worksheets("Hoja2").Activate
c = 0
n = 16384
ReDim A(n)
ReDim B(n)
Randomize
For i = 1 To n
radio = Rnd
angulo = Rnd * 2 * (WorksheetFunction.Pi)
A(i) = radio * Cos(angulo)
B(i) = radio * Sin(angulo)
Next i
For Each grafico In Worksheets("Hoja2").ChartObjects
If grafico.Name = "migas" Then
c = c + 1
End If
Next
If c = 0 Then
Set ChtObj = Worksheets("Hoja2").ChartObjects.Add(Left:=10, Top:=10, _
Width:=400, Height:=400)
With ChtObj
.Chart.ChartType = xlXYScatter
.Chart.SetSourceData Source:=Range("Hoja2!$A$1:$B$2")
.Name = "migas"
End With
End If
ActiveSheet.ChartObjects("migas").Activate
ActiveChart.SeriesCollection(1).XValues = A
ActiveChart.SeriesCollection(1).Values = B
ActiveChart.Axes(xlCategory).MaximumScale = 1
ActiveChart.Axes(xlCategory).MinimumScale = -1
ActiveChart.Axes(xlValue).MaximumScale = 1
ActiveChart.Axes(xlValue).MinimumScale = -1
ActiveChart.SetElement (msoElementLegendNone)
ActiveChart.SetElement (msoElementPrimaryValueGridLinesNone)
ActiveChart.SetElement (msoElementPrimaryCategoryAxisNone)
ActiveChart.SetElement (msoElementPrimaryValueAxisNone)
ActiveChart.SetElement (msoElementChartTitleNone)
ActiveChart.FullSeriesCollection(1).MarkerStyle = -4118
ActiveChart.FullSeriesCollection(1).MarkerSize = 2
Range("A1").Select
End Sub
Tercera macro
Sub generaChartConArray3()
Dim A() As Variant
Dim B() As Variant
Dim i As Long
Dim radio As Double
Dim angulo As Double
Dim grafico As ChartObject
Dim c As Byte
Dim n As Long
Dim ChtObj As ChartObject
Worksheets("Hoja2").Activate
c = 0
n = 16384
ReDim A(n)
ReDim B(n)
Randomize
For i = 1 To n
radio = Sqr(Rnd)
angulo = Rnd * 2 * (WorksheetFunction.Pi)
A(i) = radio * Cos(angulo)
B(i) = radio * Sin(angulo)
Next i
For Each grafico In Worksheets("Hoja2").ChartObjects
If grafico.Name = "migas" Then
c = c + 1
End If
Next
If c = 0 Then
Set ChtObj = Worksheets("Hoja2").ChartObjects.Add(Left:=10, Top:=10, _
Width:=400, Height:=400)
With ChtObj
.Chart.ChartType = xlXYScatter
.Chart.SetSourceData Source:=Range("Hoja2!$A$1:$B$2")
.Name = "migas"
End With
End If
ActiveSheet.ChartObjects("migas").Activate
ActiveChart.SeriesCollection(1).XValues = A
ActiveChart.SeriesCollection(1).Values = B
ActiveChart.Axes(xlCategory).MaximumScale = 1
ActiveChart.Axes(xlCategory).MinimumScale = -1
ActiveChart.Axes(xlValue).MaximumScale = 1
ActiveChart.Axes(xlValue).MinimumScale = -1
ActiveChart.SetElement (msoElementLegendNone)
ActiveChart.SetElement (msoElementPrimaryValueGridLinesNone)
ActiveChart.SetElement (msoElementPrimaryCategoryAxisNone)
ActiveChart.SetElement (msoElementPrimaryValueAxisNone)
ActiveChart.SetElement (msoElementChartTitleNone)
ActiveChart.FullSeriesCollection(1).MarkerStyle = -4118
ActiveChart.FullSeriesCollection(1).MarkerSize = 2
Range("A1").Select
End Sub
La segunda y tercera macro son prácticamente iguales, únicamente cambia la forma en la que elegimos el radio. En la segunda macro se hace según una distribución de probabilidad uniforme entre cero y uno. En la tercera macro lo que pretendemos es que los puntos del gráfico se distribuyan de forma uniforme por el área de la circunferencia por lo que hemos tenido que modificar la distribución de probabilidad introduciendo la raiz cuadrada de una uniforme entre cero y uno.
Puede ver un desarrollo parecido en otro lenguaje de programación en el siguiente enlace.
Canvas en HTML5+CSS+JS creando puntitos aleatorios
En él se emplea HTML5+CSS+JavaScript.
No hay comentarios:
Publicar un comentario