#Visualización

0 Seguidores · 14 Publicaciones

Visualización se refiere a las técnicas utilizadas para comunicar datos o información al codificarlas como objetos visuales (por ejemplo, puntos, líneas o barras) contenidos en los gráficos. El objetivo es comunicar información de forma clara y eficiente para los usuarios.

Artículo Ricardo Paiva · oct 8, 2025 1m read

gj :: configExplorer es una nueva extensión de VS Code que se integra con Server Manager y aprovecha Structurizr para generar diagramas de configuración de vuestros servidores.

Aquí tenéis un breve video introductorio.

0
0 22
Artículo Alberto Fuentes · feb 21, 2024 2m read

Quería compartiros hoy un pequeño truco para personalizar cómo se muestran los mensajes en el Visor de Mensajes. En concreto, cómo mostrar mensajes JSON directamente en el Visor de Mensajes en lugar de serializados como XML.

image

Los mensajes son los objetos que utilizamos para comunicar componentes de una producción de interoperabilidad. En mi caso me había definido un mensaje que utilizaba después para pasar a JSON y enviar a una API. Este mensaje está definido como un mensaje convencional y también como %JSON.Adaptor para poder exportar / importar directamente a JSON.

Class interop.msg.DeviceOrderReq Extends (Ens.Request, %JSON.Adaptor)
{

Parameter %JSONNULL As BOOLEAN = 1;

Property externalOrderId As %String(MAXLEN = "");

Property orderStatus As %String;

Property requestedServiceId As %String(MAXLEN = "");

Property patientData As interop.msg.elements.PatientData;

}

El mensaje funciona correctamente cuando hago diferentes pruebas en mi producción, sin embargo en el Visor de Mensajes aparece con la representación por defecto XML:

image

La representación es correcta, pero me sería mucho más intuitivo ver el mensaje representado directamente en JSON. Para ello, podemos sobreescribir el método %ShowContents en nuestro mensaje.

En mi caso, para poder reutilizar código me he creado una clase llamada JSONMessage. Esta clase sobreescribe el %ShowContents para mostrar la representación en JSON formateada del objeto.

Class interop.msg.JSONMessage Extends (Ens.Request, %JSON.Adaptor)
{

/// This method is called by the Management Portal to determine the content type that will be returned by the <method>%ShowContents</method> method.
/// The return value is a string containing an HTTP content type.
Method %GetContentType() As %String
{
	Quit "text/html"
}

/// This method is called by the Management Portal to display a message-specific content viewer.<br>
/// This method displays its content by writing out to the current device.
/// The content should match the type returned by the <method>%GetContentType</method> method.<br>
Method %ShowContents(pZenOutput As %Boolean = 0)
{
   do ..%JSONExportToString(.jsonExport)
    set formatter = ##class(%JSON.Formatter).%New()
    do formatter.FormatToString(jsonExport, .json)
    &html<<pre>#(json)#</pre>>
}

}

Por último, sólo queda cambiar la definición del mensaje original para que herede de JSONMessage:

Class interop.msg.DeviceOrderReq Extends (JSONMessage, Ens.Request)
{

Parameter %JSONNULL As BOOLEAN = 1;

Property externalOrderId As %String(MAXLEN = "");

Property orderStatus As %String;

Property requestedServiceId As %String(MAXLEN = "");

Property patientData As interop.msg.elements.PatientData;

}
2
0 295
Artículo Ricardo Paiva · abr 20, 2023 2m read

Apache Superset es una moderna plataforma para la visualización y exploración de datos. Superset puede reemplazar o aumentar las herramientas patentadas de business intelligence para muchos equipos. Y se puede integrar con una gran variedad de fuentes de datos.

¡Y ahora es posible utilizarla con InterSystems IRIS!

Hay disponible una demo online que usa IRIS Cloud SQL como fuente de datos.

0
0 621
Pregunta Yone Moreno · sep 21, 2022

Hola,

Estamos muy interesados en estudiar DICOM en profundidad, tanto el estándar en sí como su relación con HealthShare.

¿Podríais indicarnos algunas buenas referencias: documentación, cursos, libros, pdfs, explicaciones; para entender de qué va este estándar y cómo funciona?

Gracias por sus respuestas

Hemos leído:

https://dicom.nema.org/medical/dicom/current/output/html/part01.html

https://docs.intersystems.com/irisforhealthlatest/csp/docbook/DocBook.UI...

¿Podríais localizarnos y referenciar alguna buena documentación y/o vídeos o cursos para conocer, entender y leer sobre DICOM?

1
0 153
Artículo Muhammad Waseem · jul 12, 2022 8m read

Hola Comunidad,

Esta publicación es una introducción a mi aplicación iris-climate-change en Open Exchange.

iris-climate-change  importa el conjunto de datos Temperature Change, de la Organización de las Naciones Unidas para la Agricultura y la Alimentación (FAO), usando la funcionalidad LOAD DATA (SQL) y analiza y visualiza los datos con la ayuda del frameworkPython Flask Web, la librería Pandas Python data analysisPlotly Open Source Graphing Library for Python y la librería Plotly JavaScript Open Source Graphing.

0
0 176
Artículo Muhammad Waseem · jun 9, 2022 1m read

Alt Text

¡Hola a todos!

Solo quería compartir aquí una publicación rápida sobre mi proyecto para el Gran Premio :D

FHIR Patient Viewer es una herramienta de renderizado de una sola página, basada en Vue.js, que muestra de forma sencilla los datos devueltos de una llamada /Patient/{id}/$everything realizada a un servidor FHIR de InterSystems.

En el archivo Readme he incluido 3 cosas principales:

  1. Una demostración en video que conecta FHIR Patient Viewer a un servidor sandbox IRIS FHIR (la forma más rápida de probarlo);
  2. Un segundo video que muestra cómo usaría yo FHIR Patient Viewer en un entorno de producción (usando un backend personalizado para manejar las llamadas a la API, escrito en PHP/Laravel en mi ejemplo, pero transferible a otros lenguajes/frameworks);
  3. Instrucciones para modificar los componentes, crear tu propia versión de la herramienta y crear tus propios archivos dist.

¡Gracias a todos! ¡Ha habido una calidad extraordinaria en los proyectos presentados al Gran Premio!

0
0 212
Artículo Muhammad Waseem · mar 10, 2022 5m read

¡Hola Comunidad!

Esta publicación es una introducción a mi aplicación iris-python-apps, disponible en Open Exchange y creada usando Embedded Python y Python Flask Web Framework. La aplicación muestra algunas de las funcionalidades de Python, como la ciencia de datos, el trazado de datos, la visualización de datos y la generación de códigos QR.

image

Características

  •  Cuadro de mando de IRIS de arranque responsive

  •  Vista de los detalles del cuadro de mando junto con el registro de eventos de interoperabilidad y los mensajes

  •  Uso del trazado de Python desde IRIS

  •  Uso de Jupyter Notebook

  •  Introducción a la ciencia de datos, trazado de datos y visualización de datos

  • Generación de código QR desde Python

0
1 1651
Artículo Kurro Lopez · jun 4, 2021 3m read

La cobertura del código y su optmización del rendimiento ya han surgido muchas veces, así que la mayoría de vosotors seguro que ya conocéis la herramienta SYS.MONLBL.

A menudo, un enfoque visual para revisar el código es mucho más intuitivo que los números puros. Este es principalmente el objetivo de esta serie de artículos. Esta vez vamos a hacer una pequeña excursión lejos de Python y sus herramientas, y vamos a explorar la generación de mapas de calor de los informes ^%SYS.MONLBL.

Como recordatorio rápido, un mapa de calor es solo una herramienta de visualización concreta, que nos da una visión general de los datos, en la que los colores representan un determinado valor. En nuestro caso, los datos serán líneas de código, con el tiempo que se dedica a ellas representado en colores.

^%SYS.MONLBL

Para obtener más información sobre cómo ejecutar la monitorización línea a línea, consulta esta documentación. En resumen, vamos a trabajar con un archivo CSV como salida completa de un análisis. Es mucho más útil si realmente tenemos el código fuente que estamos tratando de analizar. Asegúrate de compilar tu código con la marca k (mantén la fuente).

Cómo preparar la salida

Como salida objetivo vamos a utilizar un documento ya preparado en html. Solo incluirá un diseño muy básico y una pequeña función en javascript para realizar el coloreado final.

<!doctype html>
<html class="no-js" lang="">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="x-ua-compatible" content="ie=edge">
        <title></title>
        <meta name="description" content="">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        
        <!-- Place favicon.ico and apple-touch-icon.png in the root directory -->
        <link rel="apple-touch-icon" href="apple-touch-icon.png">

        <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/4.2.0/normalize.min.css">
        <script src="https://cdnjs.cloudflare.com/ajax/libs/modernizr/2.8.3/modernizr.min.js"></script>
        <!--<link rel="stylesheet" href="css/main.css"> -->
            <style>
        table, th, td {
            width:"100%";
            border: 1px solid black;
            border-collapse: collapse;
        }
        pre {
            margin:1px;
        }
        th {
            text-align: left;
        }
    </style>

Por motivos de seguridad, este bloque no puede estar editado como código. El siguiente bloque ha de ir entre etiqueta Script

    function rgba(r, g,b,a){
        r = Math.floor(r);
        g = Math.floor(g);
        b = Math.floor(b);
        return ["rgba(",r,",",g,",",b,",",a,")"].join("");
    }
    function colorize() {
        var rows=$("#data tr")
        var max=Math.max.apply(Math,rows.slice(1,rows.length).map(function(){ return this.childNodes[2].textContent}))
        for (i=1;i<rows.length;i++){
            var val=rows[i].childNodes[2].textContent;
            var c=(Math.pow(1-val/max,3))*255;
            var col=rgba(255,c,c,0.7);
            console.log(col);
            rows[i].style.backgroundColor=col;
        }
    }

Aquí iria el cierre de la etiqueta script

    </head>

    <body onload="colorize()">
        <!--[if lt IE 8]>
            <p class="browserupgrade">You are using an <strong>outdated</strong> browser. Please <a href="http://browsehappy.com/">upgrade your browser</a> to improve your experience.</p>
        <![endif]-->

Por motivo de seguriad, este bloque no puede estar editado como códigoimage

<table id="data">
<tr><th>Routine</th><th>Line</th><th>Total Time</th><th>Code</th></tr>
<!--output-->
</table>


    </body>
</html>

Analizar y reunir la información

Por medio de los siguientes scripts se obtiene la información relevante del CSV generado y se introduce en nuestra plantilla:

monlbl.sh

#!/bin/bash

cat $1|grep -vi totals| awk -F"," 'FNR>1 {out="<tr><td>"$1"</td>" "<td>" $2 "</td><td>" $54 "</td><td><pre>"; for(i=55;i<=NF;i++){out=out$i","}; out=substr(out, 1, length(out)-1) "</pre></td></tr>"; print out }'

gen-heatmap.sh

#!/bin/bash
./monlbl.sh $1 > /tmp/temp.data
sed -e '/<!--output-->/r/tmp/temp.data' template.html

Que llamamos de esta forma:

./gen-heatmap.sh /tmp/report.csv > heatmap.html

Resultado final heatmap

Ajustables

Si echas un vistazo más de cerca a la función de coloreado en nuestra plantilla, verás que no estoy usando un mapeo lineal para los tiempos:

    function colorize() {
        var rows=$("#data tr")
        var max=Math.max.apply(Math,rows.slice(1,rows.length).map(function(){ return this.childNodes[2].textContent}))
        for (i=1;i<rows.length;i++){
            var val=rows[i].childNodes[2].textContent;
            var c=(Math.pow(1-val/max,3))*255;
            var col=rgba(255,c,c,0.7);
            console.log(col);
            rows[i].style.backgroundColor=col;
        }
    }

Encontré que esto funcionaba bastante bien con los ejemplos que probé, pero los resultados pueden variar. Evidentemente, se puede aumentar el exponente para llevarlo más al rojo, o viceversa.

Código

Puedes encontrar todos los archivos relevantes aquí

0
0 143
Artículo Kurro Lopez · abr 13, 2021 7m read

En el artículo anterior creamos un gráfico simple con los datos de un solo archivo. Ahora bien, como todos sabemos, a veces tenemos diferentes archivos de datos para analizar y correlacionar. Así que en este artículo vamos a cargar datos adicionales de perfmon y aprenderemos a representarlos en el mismo gráfico.

Como podemos querer utilizar en informes o en una página web nuestros gráficos generados, también revisaremos formas de exportar los gráficos generados.

Cargando datos de Windows Perfmon

Los datos de perfmon extraídos del informe estándar de pbuttons tienen un formato de datos un poco peculiar. A primera vista es un archivo csv bastante sencillo. La primera fila contiene los encabezados de las columnas, las filas siguientes los datapoints. Sin embargo, para nuestros propósitos tendremos que hacer algo con las comillas que rodean las entradas de los valores. Utilizando el enfoque estándar para analizar el archivo en python, terminaremos con columnas de objetos de tipo cadena, que no funcionan bien para ser representados de forma gráfica.

perfmonfile="../vis-part2/perfmon.txt"
perfmon=pd.read_csv(perfmonfile,
                    header=0,
                    index_col=0,
                    converters={0: parse_datetime
                    })

A diferencia del archivo mgstat que utilizamos en la primera parte, los nombres de los encabezados están en la primera fila. Queremos que la primera columna defina nuestro índice (de esta manera no tenemos que volver a indexar el dataframe como hicimos la última vez). Por último, debemos analizar la primera columna para que realmente represente un DateTime. De lo contrario, terminaríamos con un índice de cadenas. Para ello, definimos una pequeña función de ayuda para analizar las fechas de perfmon:

def parse_datetime(x):
    dt = datetime.strptime(x, '%m/%d/%Y %H:%M:%S.%f')

    return dt

El parámetro ~~~conventers~~~ nos permite pasarlo como controlador de la primera columna.

Después de ejecutar esto, terminamos con los datos de perfmon en un DataFrame:

<class 'pandas.core.frame.DataFrame'>
Index: 2104 entries, 01/03/2017 00:01:19.781 to 01/03/2017 17:32:51.957
Columns: 105 entries, \\WEBSERVER\Memory\Available MBytes to \\WEBSERVER\System\Processor Queue Length
dtypes: float64(1), int64(11), object(93)
memory usage: 1.7+ MB

Ten en cuenta que la mayoría de las columnas actualmente son un object. Para convertir estas columnas a un formato utilizable, emplearemos la función to_numeric. Aunque podríamos usar apply para llamarlo en cada columna, eso estropearía nuestro índice de nuevo. Así que vamos a trazar los datos directamente mientras se canaliza a través de eso.

#Plotting En esta ocasión, nos interesa representar el tiempo total privilegiado de todas las CPUs. Lamentablemente, los números de las columnas no son constantes y varían con el número de CPU y drives. Así que tendrás que observar y averiguar qué columna es. En mi ejemplo es 91:

perfmon.columns[91]

'\\\\WEBSERVER\\Processor(_Total)\\% Privileged Time'

Utilizaremos más o menos el mismo enfoque que la última vez para crear un gráfico con Glorefs, Rdratio y nuestro nuevo Privileged Time:

plt.figure(num=None, figsize=(16,5), dpi=80, facecolor='w', edgecolor='k')
host = host_subplot(111, axes_class=AA.Axes)
plt.subplots_adjust(right=0.75)

par1 = host.twinx()
par2 = host.twinx()
offset = 60
new_fixed_axis = par2.get_grid_helper().new_fixed_axis
par2.axis["right"] = new_fixed_axis(loc="right",axes=par2,offset=(offset, 0))
par2.axis["right"].toggle(all=True)

host.set_xlabel("time")
host.set_ylabel("Glorefs")

par1.set_ylabel("Rdratio")
par2.set_ylabel("Privileged Time")
ws=30
p1,=host.plot(data.Glorefs,label="Glorefs")
p2,=par1.plot(data.Rdratio,label="Rdratio")
p3,=par2.plot(pd.to_numeric(perfmon[perfmon.columns[91]],errors='coerce'),label="PTime")

host.legend()

host.axis["left"].label.set_color(p1.get_color())
par1.axis["right"].label.set_color(p2.get_color())
par2.axis["right"].label.set_color(p3.get_color())

plt.draw()
plt.show()

Aquí es donde se utiliza to_numeric:

p3,=par2.plot(pd.to_numeric(perfmon[perfmon.columns[91]],errors='coerce'),label="PTime")

gráfica

Cómo redirigir la salida

Mientras que Notebook es realmente bueno para tener un vistazo rápido de nuestros datos, con el tiempo nos gustaría ser capaces de ejecutar nuestros scripts de forma no interactiva, por lo que queremos que nuestros gráficos salgan como imágenes. Obviamente, realizar una captura de pantalla implica demasiado trabajo manual, así que utilizaremos la función pyplot savefig().

Reemplazaremos las llamadas draw() y show() con la llamada savefig():

#plt.draw()
#plt.show()
plt.savefig("ptime-out.png")

que nos dará el png en nuestro directorio de trabajo actual.

Salida avanzada

Como un pequeño ejercicio adicional vamos a echar un vistazo a Bokeh. Una de las muchas útiles características que bokeh está añadiendo a nuestra caja de herramientas, es la capacidad de generar nuestros gráficos como un archivo HTML interactivo. Interactivo en este caso significa que podemos ampliar y desplazarnos por nuestros datos. Añade la capacidad de vincular gráficos entre sí y podrás crear fácilmente renderizados interactivos de datos de pbuttons (u otros). Estos son especialmente útiles, porque se ejecutan en cualquier navegador y se pueden distribuir fácilmente a varias personas.

Por ahora, nuestro objetivo es añadir solo dos gráficos a nuestra salida. Nos gustaría obtener Glorefs y el tiempo privilegiado de perfom en una página.

Para eso primero tendremos que importar bokeh:

from bokeh.plotting import *

Vamos a definir un par de propiedades y etiquetas, así como el tamaño de cada gráfico. Después, representaremos los datos de los objetos que recogimos antes y ya hemos terminado.

Fíjate en el comentario output_notebook(), esto renderizaría la salida directamente en nuestro jupyter notebook. Estamos utilizando output_file ya que nos gustaría tener un archivo que podamos distribuir.

output_file("mgstat.html")
#output_notebook()
TOOLS="pan,box_zoom,reset,save"

left = figure(tools=TOOLS,x_axis_type='datetime',
    title="Glorefs",width=600, height=350,
   x_axis_label='time'
)
right=figure(tools=TOOLS,x_axis_type='datetime',
    title="PTime",width=600, height=350,
   x_axis_label='time',x_range=left.x_range
)
left.line(data.index,data.Glorefs,legend="Glorefs",line_width=1)
right.line(perfmon.index,pd.to_numeric(perfmon[perfmon.columns[91]],errors='coerce'),legend="privileged time",line_width=1)
p=gridplot([[left,right]])
show(p)

El ingrediente clave aquí es la vinculación de los rangos de nuestros dos gráficos con x_range=left.x_range. Esto actualizará la ventana derecha con nuestra selección/zoom/movimiento desde la izquierda (y viceversa).

La lista de HERRAMIENTAS es solo la lista de herramientas que nos gustaría tener en nuestra pantalla resultante. Usando gridplot vamos a poner los dos gráficos uno al lado del otro:

mgstat-bokeh

También puedes echar un vistazo al html resultante en el repositorio de github. Parece que es demasiado grande para publicarlo directamente por medio de github, así que tendrás que descargarlo.

Conclusiones

En este artículo, exploramos la extracción de datos de diferentes fuentes y su representación en el mismo gráfico. También estamos gestionando datos con frecuencia de muestreo diferente (apuesto a que no te diste cuenta ;D ). Bokeh nos ofrece una potente herramienta para crear vistas interactivas fácilmente distribuibles para nuestros gráficos.

En próximos artículos exploraremos más cosas para representar gráficamente: csp.log, registros de acceso de apache/iis, eventos de cconsole.log. Si tienes alguna sugerencia sobre algunos datos que te gustaría ver procesados con python, no dudes en comentarlo.

¡Comparte tus experiencias! ¡Esto está pensado como un aprendizaje interactivo!

Enlaces

Puedes encontrar todos los archivos de este artículo aquí También puedes ver la nueva herramienta de extracción pButtons de @murrayo, basada en algunas de las técnicas comentadas: https://github.com/murrayo/yape

0
0 113
Artículo Bernardo Linarez · oct 28, 2020 12m read

Prometheus es uno de los sistemas de monitorización adaptado para recoger datos de series temporales.

Su instalación y configuración inicial son relativamente sencillos. El sistema tiene un subsistema gráfico integrado llamado PromDash para la visualización de datos, pero los desarrolladores recomiendan usar un producto de otro proveedor, llamado Grafana. Prometheus puede monitorizar muchas cosas (hardware, contenedores, distintos sistemas de gestión de base de datos), pero en este artículo me gustaría analizar la monitorización de una instancia de Caché (para ser exactos, será una instancia de Ensemble, pero las métricas serán de Caché). Si te interesa, sigue leyendo.

1
0 457
Artículo Kurro Lopez · jul 30, 2020 9m read

Este es el primer artículo de una serie que se sumerge en herramientas de visualización y análisis de datos de series temporales. Obviamente, estamos más interesados en analizar los datos relacionados con el rendimiento que podemos recopilar de la familia de productos Caché. Sin embargo, como veremos más adelante, no estamos limitados a eso. Por ahora estamos explorando Python y las bibliotecas/herramientas disponibles dentro de ese ecosistema.

La serie está estrechamente vinculada a la excelente serie de Murray sobre el rendimiento y la supervisión de Caché. (ver aquí) y mas especificamente este artículo.

Descargo de responsabilidad I: Si bien hablaré de pasada sobre la interpretación de los datos que estamos viendo, hablar de eso en detalle distraería demasiado del objetivo real. Recomiendo encarecidamente la serie de Murray para comenzar, para obtener una comprensión básica del tema.

Descargo de responsabilidad II: Existen miles de millones de herramientas que le permiten visualizar los datos recopilados. Muchos de ellos trabajan directamente con los datos que obtiene de mgstat y sus amigos, o solo necesitan un ajuste mínimo. Esta no es una publicación de 'esta solución es la mejor'. Es solo una de las formas en que he encontrado útil y eficiente trabajar con los datos.

Descargo de responsabilidad III: La visualización y el análisis de datos es un campo altamente adictivo, emocionante y divertido para sumergirse. Puede perder algo de tiempo libre por esto. ¡Usted ha sido advertido!

Entonces, sin más preámbulos, profundicemos en ello.

Prerequisitos

Para comenzar, necesitará algunas herramientas y bibliotecas:

  • Jupyter notebooks
  • Python (3)
  • varias bibliotecas de Python que usaremos en el futuro

Python (3) Necesitará Python en su máquina. Hay numerosas formas de instalarlo en varias arquitecturas. Yo uso homebrew en mi mac, lo que lo hizo fácil:

brew install python3

Solicite a google instrucciones para su plataforma favorita.

Jupyter notebooks: Si bien no es técnicamente necesario, el Jupyter notebooks hace que trabajar en scripts de python sea muy fácil. Le permite ejecutar interactivamente y mostrar scripts de Python desde una ventana del navegador. También permite trabajar en colaboración en scripts. Como hace que sea muy fácil experimentar y jugar con código, es muy recomendable.

pip3 install jupyter

(de nuevo, habla con $search-engine ;)

Librerías Python Mencioné las diferentes bibliotecas de Python mientras las usamos en el futuro. Si obtiene un error en una declaración import, una buena primera aproximación es siempre asegurarse de tener instalada la biblioteca:

pip3 install matplotlib

Empezando

Suponiendo que tiene todo instalado en su máquina, debería poder ejecutar

jupyter notebook

de un directorio. Esto debería abrir automáticamente una ventana del navegador con una interfaz de usuario simple. emtpy-notebook

Continuaremos y crearemos un nuevo cuaderno a través del menú y agregaremos un par de declaraciones de importación a nuestra primera celda de código (New -> Notebooks -> Python3):

notebook-imports

import math
import pandas as pd
import mpl_toolkits.axisartist as AA
from mpl_toolkits.axes_grid1 import host_subplot
import matplotlib.pyplot as plt
from datetime import datetime
from matplotlib.dates import DateFormatter

En cuanto a las bibliotecas que estamos importando, solo quiero mencionar algunas:

  • Pandas "es una biblioteca de código abierto con licencia BSD que proporciona estructuras de datos y herramientas de análisis de datos de alto rendimiento y fáciles de usar para el lenguaje de programación Python". Lo que permite trabajar eficientemente con grandes conjuntos de datos. Si bien los conjuntos de datos que obtenemos de pButtons, de ninguna manera son 'big data'. Sin embargo, nos consolaremos con el hecho de que podríamos ver muchos datos a la vez. Imagine que ha estado recolectando pButtons con muestreo de 24 h/2 segundos durante los últimos 20 años en su sistema. Podríamos graficar eso.
  • Matplotlib "matplotlib es una biblioteca de trazado 2D de python que produce cifras de calidad de publicación en una variedad de formatos impresos y entornos interactivos en todas las plataformas". Este será el principal motor de gráficos que vamos a utilizar (por ahora).

Si recibe un error al ejecutar la celda de código actual (shortcut: Ctrl+Enter) (lista de atajos), asegúrese de verificar que los tenga instalados.

También notará que cambié el nombre del cuaderno Sin título, para hacerlo, simplemente puede hacer clic en el título.

Cargando algunos datos

Ahora que pusimos un poco de terreno, es hora de obtener algunos datos. Por suerte, Pandas proporciona una manera fácil de cargar datos CSV. Ya que tenemos un conjunto de datos de mgstat por ahí in csv-format, we'll just use that.

mgstatfile = '/Users/kazamatzuri/work/proj/vis-articles/part1/mgstat.txt'
data = pd.read_csv(
    mgstatfile, 
    header=1,
    parse_dates=[[0,1]]
   )

Nosotras estamos utilizando el read_csv comando para leer directamente los datos de mgstat en un DataFrame. Consulte la documentación completa para una descripción completa de las opciones. En resumen: simplemente estamos pasando el archivo para leerlo y decirle que la segunda línea (¡basada en 0!) Contiene los nombres de los encabezados. Dado que mgstat divide los campos de fecha y hora en dos campos, también necesitamos combinarlos con el parámetro parse_dates.

data.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 25635 entries, 0 to 25634
Data columns (total 37 columns):
Date_       Time        25635 non-null datetime64[ns]
  Glorefs               25635 non-null int64
 RemGrefs               25635 non-null int64
 GRratio                25635 non-null int64
  PhyRds                25635 non-null int64
 Rdratio                25635 non-null float64
 Gloupds                25635 non-null int64
 RemGupds               25635 non-null int64
 Rourefs                25635 non-null int64
 RemRrefs               25635 non-null int64
  RouLaS                25635 non-null int64
 RemRLaS                25635 non-null int64
  PhyWrs                25635 non-null int64
   WDQsz                25635 non-null int64
  WDtmpq                25635 non-null int64
 WDphase                25635 non-null int64
  WIJwri                25635 non-null int64
  RouCMs                25635 non-null int64
 Jrnwrts                25635 non-null int64
   GblSz                25635 non-null int64
 pGblNsz                25635 non-null int64
 pGblAsz                25635 non-null float64
   ObjSz                25635 non-null int64
 pObjNsz                25635 non-null int64
 pObjAsz                25635 non-null int64
   BDBSz                25635 non-null int64
 pBDBNsz                25635 non-null int64
 pBDBAsz                25635 non-null float64
  ActECP                25635 non-null int64
  Addblk                25635 non-null int64
 PrgBufL                25635 non-null int64
 PrgSrvR                25635 non-null int64
  BytSnt                25635 non-null int64
  BytRcd                25635 non-null int64
  WDpass                25635 non-null int64
  IJUcnt                25635 non-null int64
 IJULock                25635 non-null int64
dtypes: datetime64[ns](1), float64(3), int64(33)
memory usage: 7.2 MB

nos da una buena visión general del DataFrame recopilado.

Trabajando con los datos

Dado que algunos nombres de campo contienen espacios y guión bajo ("Date_ Time") es bastante difícil de manejar, seguiremos adelante y eiminamos espacios y cambiaremos el nombre de la primera columna:

data.columns=data.columns.str.strip()
data=data.rename(columns={'Date_       Time':'DateTime'})

El Marco de datos predeterminado es un RangeIndex. Esto no es muy útil para ver nuestros datos. Como tenemos disponible una columna DateTime bastante práctica, seguiremos adelante y la configuraremos como índice:

data.index=data.DateTime

Ahora estamos listos para crear una versión inicial de nuestra trama. Como esta es siempre una de las primeras cosas a tener en cuenta, usemos Glorefs para esto:

plt.figure(num=None, figsize=(16,5), dpi=80, facecolor='w', edgecolor='k')
plt.xticks(rotation=70)
plt.plot(data.DateTime,data.Glorefs)
plt.show()

Primero le decimos a la biblioteca en qué tamaño queremos el gráfico. También queremos que las etiquetas del eje x giren un poco, para que no se superpongan. Finalmente graficamos DateTime vs Glorefs y mostramos el gráfico. Esto nos da algo como el siguiente gráfico.

Glorefs

Podemos reemplazar fácilmente Glorefs con cualquiera de las otras columnas para tener una idea general de lo que está sucediendo.

Combinando gráficos

En algún momento es bastante útil mirar múltiples gráficos a la vez. Entonces, la idea de dibujar varias parcelas en una sola gráfica parece natural. Si bien es muy sencillo hacerlo solo con matplotlib:

plt.plot(data.DateTime,data.Glorefs)
plt.plot(data.DateTime,data.PhyRds)
plt.show()

Esto nos dará más o menos la misma gráfica que antes. El problema, por supuesto, es la escala y. Dado que Glorefs sube a millones, mientras que los PhyRds generalmente están en los 100 (a miles), no los vemos.

Para resolver esto, necesitaremos usar el kit de herramientas axisartist previamente importado.

plt.gcf()
plt.figure(num=None, figsize=(16,5), dpi=80, facecolor='w', edgecolor='k')
host = host_subplot(111, axes_class=AA.Axes)
plt.subplots_adjust(right=0.75)

par1 = host.twinx()
par2 = host.twinx()
offset = 60
new_fixed_axis = par2.get_grid_helper().new_fixed_axis
par2.axis["right"] = new_fixed_axis(loc="right",axes=par2,offset=(offset, 0))
par2.axis["right"].toggle(all=True)

host.set_xlabel("time")
host.set_ylabel("Glorefs")
par1.set_ylabel("Rdratio")
par2.set_ylabel("PhyRds")

p1,=host.plot(data.Glorefs,label="Glorefs")
p2,=par1.plot(data.Rdratio,label="Rdratio")
p3,=par2.plot(data.PhyRds,label="PhyRds")

host.legend()

host.axis["left"].label.set_color(p1.get_color())
par1.axis["right"].label.set_color(p2.get_color())
par2.axis["right"].label.set_color(p3.get_color())

plt.draw()
plt.show()

El breve resumen es: agregaremos dos ejes y al diagrama, que tendrán su propia escala. Si bien utilizamos implícitamente la subtrama en nuestro primer ejemplo, en este caso necesitamos acceder a ella directamente para poder agregar el eje y las etiquetas. Establecemos un par de etiquetas y los colores. Después de agregar una leyenda y conectar los colores a las diferentes parcelas, terminamos con una imagen como esta:

combinado

Comentarios finales

Esto ya nos da un par de herramientas muy poderosas para trazar nuestros datos. Exploramos cómo cargar datos de mgstat y crear algunos gráficos básicos. En la siguiente parte, jugaremos con diferentes formatos de salida para nuestros gráficos y obtendremos más datos.

Comentarios y preguntas son alentados! ¡Comparte tus experiencias!

-Fab

ps. el cuaderno para esto está disponible aquí

0
0 323
Artículo Joel Espinoza · feb 27, 2020 15m read

Hola Comunidad:

Esta publicación está dedicada a la tarea de supervisar una instancia de Caché usando SNMP. Algunos usuarios de Caché probablemente ya lo hacen de una u otra forma. Hace ya mucho que el paquete de Caché estándar soporta la supervisión por SNMP, pero no todos los parámetros necesarios vienen "listos para usar". Por ejemplo, sería bueno poder supervisar el número de sesiones CSP, obtener información detallada sobre el uso de la licencia, KPI particulares del sistema en uso, etc. Después de leer este artículo, sabrás cómo agregar tus parámetros a la supervisión de Caché mediante SNMP.

4
0 2355