Uso de Plotly Library para visualización interactiva de datos en Python

En mi artículo anterior, expliqué cómo se puede usar la biblioteca Pandas para trazar gráficos básicos y de series de tiempo. Mientras que las bibliotecas Pandas, Matplotlib y Seaborn...

En mi Artículo anterior, expliqué cómo se puede usar la biblioteca Pandas para trazar gráficos básicos y de series de tiempo. Mientras que pandas, matplotlib y nacido en el mar Las bibliotecas son excelentes bibliotecas de trazado de datos, solo pueden trazar gráficos estáticos. Los gráficos estáticos son como imágenes simples no interactivas. En la mayoría de los casos, los gráficos estáticos son suficientes para transmitir la información. Sin embargo, en algunos casos, es posible que desee agregar interactividad del usuario a sus gráficos.

En este artículo, veremos cómo se puede usar la biblioteca trama de Python para trazar gráficos interactivos. Graficaremos datos geográficos utilizando plotly y explicaremos cómo un usuario puede interactuar con dichos gráficos.

Instalación de bibliotecas requeridas

Para instalar la biblioteca Plotly usando la utilidad "pip", debe ejecutar el siguiente comando:

1
$ pip install plotly

Además de Plotly, también usaremos Gemelos, que funciona como un conector entre la biblioteca de Pandas y Plotly, y nos ayuda a trazar gráficos interactivos directamente usando un Marco de datos de pandas.

Para instalar Cufflinks usando pip, ejecute el siguiente script:

1
$ pip install cufflinks

Importación de bibliotecas requeridas

Plotly es básicamente una biblioteca en línea que aloja sus visualizaciones de datos, sin embargo, también proporciona un paquete de datos fuera de línea que se puede usar para dibujar gráficos interactivos fuera de línea.

Antes de que podamos ejecutar Plotly en el cuaderno Jupyter, que estoy usando para ejecutar mis scripts, necesito importar las bibliotecas Plotly y Cufflinks junto con Numpy y Pandas como de costumbre.

El siguiente script importa las bibliotecas Numpy y Pandas:

1
2
3
import pandas as pd
import numpy as np
%matplotlib inline

A continuación, debemos importar las versiones sin conexión de los módulos de Plotly que usaremos en este artículo. El siguiente script hace eso:

1
from plotly.offline import download_plotlyjs, init_notebook_mode, plot, iplot

Antes de que podamos ejecutar nuestros scripts, necesitamos conectar el JavaScript a nuestro cuaderno. Dado que los gráficos de Plotly son interactivos, hacen uso de JavaScript detrás de escena. Los scripts que vamos a ejecutar se ejecutarán en el cuaderno de Jupyter. Para conectar el cuaderno Jupyter con JavaScript, debemos ejecutar el siguiente script:

1
init_notebook_mode(connected=True)

Finalmente, necesitamos importar la biblioteca Cufflink y asegurarnos de que la usaremos sin conexión. Para hacerlo, ejecute el siguiente script:

1
2
import cufflinks as cf
cf.go_offline()

Ahora tenemos todo lo que necesitamos para dibujar gráficos Plotly interactivos dentro de nuestros cuadernos Jupyter.

Plotly para gráficos básicos

En esta sección, usaremos la biblioteca Plotly para dibujar gráficos interactivos básicos. En la siguiente sección, veremos cómo se puede utilizar Plotly para trazar datos geográficos.

El conjunto de datos

El conjunto de datos que vamos a utilizar para esta sección es el conjunto de datos "Consejos" que se descarga de forma predeterminada con la biblioteca Seaborn. El conjunto de datos contiene información sobre la cantidad gastada por un grupo de personas en el almuerzo y la cena. El conjunto de datos contiene género, precio, propinas, edad, tamaño, día, hora y si las personas que almorzaron o cenaron eran fumadores o no.

El siguiente script importa el conjunto de datos y muestra las primeras cinco filas del conjunto de datos:

1
2
3
4
5
import seaborn as sns

dataset = sns.load_dataset('tips')

dataset.head()

La salida del script se ve así:

{.img-responsive}

A partir del resultado, puede ver que nuestro conjunto de datos contiene tres columnas numéricas: total_bill, propina y tamaño y cuatro columnas categóricas: sexo, fumador, día y hora.

Antes de usar Plotly para dibujar diagramas interactivos, recordemos cómo usamos Pandas para dibujar gráficos estáticos. Llamemos al método plot() en nuestro marco de datos para ver cómo los pandas trazan gráficos estáticos. Graficaremos los valores para las columnas 'total_bill', 'tip' y 'sex'. Mira el siguiente guión:

1
2
dataset2 = dataset[["total_bill", "tip", "size"]]
dataset2.plot()

Puede ver que para trazar un gráfico, simplemente llamamos al método trazar en nuestro marco de datos.

Producción:

{.img-responsive}

Desde la salida, puede ver el gráfico de líneas estáticas para la columna 'total_bill' y 'tips'.

Ahora veamos cómo podemos dibujar diagramas interactivos usando Plotly. En la sección donde importamos las bibliotecas, importamos la función plot() del módulo plotly.offline. Para trazar gráficos interactivos utilizando el marco de datos de Pandas, simplemente necesitamos llamar al método iplot() en lugar del método plot. Echa un vistazo al siguiente ejemplo:

1
dataset2.iplot()

Una vez que ejecute el script anterior, debería ver un diagrama de líneas interactivo para las columnas total_bill, tip y sex como se muestra a continuación:

Si pasa el cursor sobre el gráfico, debería ver que los valores cambian. Puede acercar y alejar el gráfico usando las opciones disponibles en la esquina superior derecha del gráfico. También puede agregar y eliminar columnas del gráfico. Finalmente, también puede guardar el gráfico como una imagen estática.

En el resto de la sección, trazaremos algunas de las gráficas interactivas más utilizadas usando Plotly.

El gráfico de barras

Para trazar el diagrama de barras interactivo usando Plotly, puede usar la función iplot(). Debe pasar "bar" como valor para el parámetro kind de la función iplot(). Además, debe pasar la lista de columnas categóricas para las que desea trazar sus gráficos al atributo x. Finalmente, la columna numérica se pasa como valor al atributo y. El siguiente script traza un gráfico de barras para las columnas time y sex en el eje x y total_bill en el eje y.

1
dataset.iplot(kind='bar', x=['time', 'sex'],y='total_bill')

Producción:

Puede ver en la salida que se han trazado cuatro barras para la factura total. Las barras muestran todas las combinaciones posibles de valores en las columnas sexo y tiempo.

Además de especificar columnas para los diagramas de barras, simplemente puede llamar a una función agregada en el marco de datos de Pandas y luego llamar a la función iplot() y pasar "bar" como valor para el atributo kind. Esto trazará la barra para cada columna numérica de acuerdo con la función agregada. Por ejemplo, si desea trazar el diagrama de barras que contiene los valores promedio para las columnas total_bill, tip y size, puede usar el siguiente script:

1
dataset.mean().iplot(kind='bar')

Producción:

En la salida, puede ver los diagramas de barras con valores medios para las columnas total_bill, tip y size.

Además de los gráficos de barras verticales, también puede trazar gráficos de barras horizontales. Todo lo que tiene que hacer es pasar "barh" como atributo al parámetro kind, como se muestra en el siguiente script:

1
dataset.mean().iplot(kind='barh')

Producción:

En el resultado, puede ver los gráficos de barras horizontales para los valores medios de las columnas total_bill, tip y size.

El gráfico de dispersión

Para trazar un diagrama de dispersión interactivo, debe pasar "scatter" como valor para el parámetro kind de la función iplot(). Además, debe pasar los nombres de las columnas para los ejes x e y. El siguiente script traza un diagrama de dispersión para la columna total_bill en el eje x y la columna tip en el eje y.

1
dataset.iplot(kind='scatter', x='total_bill', y='tip', mode='markers')

Producción:

Pase el mouse sobre el gráfico interactivo para ver los valores cambiantes de las columnas total_bill y tip.

El diagrama de caja {#el diagrama de caja}

En uno de mis artículos anteriores, expliqué qué es un diagrama de caja y cómo podemos dibujarlo usando la biblioteca Seaborn. El diagrama de caja traza la información del cuartil para las columnas numéricas. La distancia entre el bigote inferior y la parte inferior de la caja muestra el primer cuartil. La distancia entre la parte inferior del cuadro y el centro del cuadro muestra el segundo cuartil. De manera similar, la distancia desde el centro de la caja hasta el extremo superior de la caja cuantifica el tercer cuartil, mientras que la distancia desde la parte superior de la caja hasta el bigote superior muestra el último cuartil.

Con Plotly, puede dibujar diagramas de caja interactivos. Todo lo que tienes que hacer es pasar el box como valor al parámetro kind de la función iplot() como se muestra a continuación:

1
dataset2.iplot(kind='box')

En el resultado, verá diagramas de caja para todas las columnas numéricas en los datos, es decir, total_bill, tip y size.
Producción:

La trama histórica {#la trama histórica}

La biblioteca Plotly también se puede usar para trazar gráficos de histogramas interactivos para cualquier columna en el conjunto de datos. Para hacerlo, debe pasar "hist" como valor al parámetro kind de la función iplot(). También puede especificar el número de contenedores usando el atributo bins. El siguiente script traza el histograma para la columna total_bill:

1
dataset['total_bill'].iplot(kind='hist',bins=25)

Producción:

El diagrama de matriz de dispersión

El diagrama de matriz de dispersión es básicamente un conjunto de todos los diagramas de dispersión para columnas numéricas en su conjunto de datos.

1
dataset2.scatter_matrix()

El diagrama de dispersión

El gráfico de dispersión muestra la dispersión entre dos o más columnas numéricas en cualquier punto en particular. Por ejemplo, para ver el margen entre total_bil y propina, puede usar la función de margen de la siguiente manera:

1
dataset[['total_bill','tip']].iplot(kind='spread')

Producción:

A partir de la salida, puede ver que a medida que aumenta total_bill, también aumenta la diferencia entre total_bill y tip.

Gráficos 3D

Finalmente, además de los gráficos en 2D, también puede crear gráficos interactivos en 3D utilizando la biblioteca Plotly. Por ejemplo, para ver el gráfico 3D de las columnas total_bill, tip y size, ejecute el siguiente script.

1
2
dataset2 = dataset[["total_bill", "tip", "size"]]
data = dataset2.iplot(kind='surface', colorscale='rdylbu')

En la salida, puede ver el gráfico en 3D, puede moverlo, girarlo y acercar y alejar el gráfico.

Producción:

En esta sección, vimos algunas de las tramas interactivas más utilizadas que ofrece Plotly. En la siguiente sección, veremos cómo se puede usar la biblioteca Plotly para trazar datos geográficos.

Plotly para parcelas geográficas

Para dibujar parcelas geográficas con Plotly, usaremos Choropleth Maps. Los mapas de coropletas son tipos especiales de gráficos Plotly que se utilizan para trazar datos geográficos. La documentación detallada sobre cómo usar los mapas de coropletas está disponible aquí.

En esta sección veremos, con la ayuda de ejemplos, cómo dibujar mapas geográficos de Estados Unidos y de todo el mundo. Pero antes de escribir el código para trazar los gráficos geográficos, primero importemos las bibliotecas deseadas.

1
2
3
4
5
6
import plotly.plotly as py
import plotly.graph_objs as go
from plotly.offline import download_plotlyjs, init_notebook_mode, plot, iplot

init_notebook_mode(connected=True)
import pandas as pd

Mapas geográficos de los Estados Unidos

Hay cuatro pasos para dibujar mapas geográficos utilizando Plotly.

Paso 1: crear un diccionario de datos

El primer paso es crear un diccionario de datos que realmente contenga los datos que desea mostrar en el mapa. Para hacer esto, ejecute el siguiente script, que explicaré línea por línea después de eso.

1
2
3
4
5
6
7
8
map_data = dict(type='choropleth',
            locations=['MI', 'CO', 'FL', 'IN'],
            locationmode='USA-states',
            colorscale='Portland',
            text=['Michigan', 'Colorado', 'Florida', 'Indiana'],
            z=[1.0,2.0,3.0,4.0],
            colorbar=dict(title="USA States")
           )

Debe especificar valores para varias claves en el diccionario de datos. Son los siguientes:

  1. tipo: Dado que estamos usando mapas de coropletas, el tipo siempre será coropletas.
  2. ubicaciones: Aquí necesitamos pasar las abreviaturas de los estados que queremos mostrar en nuestro mapa. Se mostrarán cuatro estados en nuestro mapa: 'Michigan (MI)', 'Colorado (CO)', 'Florida (FL), 'Indiana (IN)'
  3. modo de ubicación será Estado de EE. UU. ya que solo estamos mostrando el mapa de los Estados Unidos.
  4. escala de colores: Esta clave se utiliza para especificar el color de la trama. Consulta la documentación para ver más opciones de color.
  5. texto: contiene una lista de cadenas que se mostrarán cuando el mouse se desplace sobre la ubicación del estado.
  6. La tecla z contiene una lista de valores numéricos que se mostrarán cuando el mouse se desplace sobre la ubicación del estado.
  7. colorbar es un diccionario. Para la tecla título, puede especificar el texto que se mostrará en la barra de colores.
Paso 2: Crear un diseño

Una vez que haya creado un diccionario de datos, el siguiente paso es crear el diccionario de diseño. El diccionario de diseño para EE. UU. es simple, como se muestra en el siguiente script.

1
map_layout = dict(geo = {'scope':'usa'})

El diccionario toma otro diccionario llamado geo. Pasamos el valor "usa" para la clave scope ya que nuestro mapa solo se limita a EE. UU.

Paso 3: Crear objeto gráfico

Si observa la sección donde importamos las bibliotecas, importamos la clase plotly.graph_objs. El tercer paso es crear un objeto de este gráfico. Para hacerlo, debemos llamar a la función Figura desde el objeto. El objeto toma dos parámetros: data y layout. Pasaremos nuestro diccionario de datos al primer parámetro y el diccionario de diseño al segundo parámetro, como se muestra a continuación:

1
map_actual = go.Figure(data=[map_data], layout=map_layout)
Paso 4: llamar al método iplot()

El paso final es llamar a la función iplot() y pasarle el objeto gráfico que creamos en el tercer paso como se muestra a continuación:

1
iplot(map_actual)

En el resultado, verá el gráfico geográfico de cuatro estados de EE. UU. Puede ver que el resto del estado no ha sido coloreado ya que no especificamos ninguna información sobre esos estados. Si pasa el mouse sobre los estados coloreados, verá los valores correspondientes de las teclas texto y z que especificamos cuando creamos nuestro diccionario de datos.

Mapas geográficos de los Estados Unidos mediante CSV {#mapas geográficos de los estados unidos mediante csv}

Ahora tenemos una idea básica de cómo podemos crear gráficos geográficos usando Plotly y mapas de coropletas. Ahora vamos a crear un mapa más complejo. Veremos cómo podemos usar datos de un archivo CSV para crear un gráfico geográfico. Crearemos un mapa geográfico que mostrará el PIB per cápita de todos los estados de los Estados Unidos.

El conjunto de datos

El conjunto de datos para esta sección se puede descargar desde este Enlace Kaggle, que viene en formato CSV. He cambiado el nombre del archivo por motivos de legibilidad.

El siguiente script importa el conjunto de datos e imprime sus primeras cinco filas en la consola.

1
2
df = pd.read_csv(r'E:/state_gdp.csv')
df.head()

La salida se ve así:

{.img-responsive}

El conjunto de datos contiene los nombres de los estados de EE. UU. en la columna Área. El conjunto de datos también contiene el PIB per cápita para los cinco años de 2013 a 2017. Trazaremos los datos para el año 2017.

Un problema con el conjunto de datos es que contiene los nombres completos de los estados, mientras que los mapas de coropletas aceptan la abreviatura de los nombres de los estados. Lo primero que debemos hacer es agregar una columna a nuestro conjunto de datos que contenga las abreviaturas de los nombres de los estados.

Una forma de hacer esto es crear un diccionario para los nombres de los estados y sus abreviaturas y luego crear una columna que contenga los valores abreviados de ese diccionario. El siguiente script crea un diccionario donde las claves son los nombres completos de los estados y los valores son las abreviaturas de los estados correspondientes:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
us_state_abbrev = {
    'Alabama': 'AL',
    'Alaska': 'AK',
    'Arizona': 'AZ',
    'Arkansas': 'AR',
    'California': 'CA',
    'Colorado': 'CO',
    'Connecticut': 'CT',
    'Delaware': 'DE',
    'Florida': 'FL',
    'Georgia': 'GA',
    'Hawaii': 'HI',
    'Idaho': 'ID',
    'Illinois': 'IL',
    'Indiana': 'IN',
    'Iowa': 'IA',
    'Kansas': 'KS',
    'Kentucky': 'KY',
    'Louisiana': 'LA',
    'Maine': 'ME',
    'Maryland': 'MD',
    'Massachusetts': 'MA',
    'Michigan': 'MI',
    'Minnesota': 'MN',
    'Mississippi': 'MS',
    'Missouri': 'MO',
    'Montana': 'MT',
    'Nebraska': 'NE',
    'Nevada': 'NV',
    'New Hampshire': 'NH',
    'New Jersey': 'NJ',
    'New Mexico': 'NM',
    'New York': 'NY',
    'North Carolina': 'NC',
    'North Dakota': 'ND',
    'Ohio': 'OH',
    'Oklahoma': 'OK',
    'Oregon': 'OR',
    'Pennsylvania': 'PA',
    'Rhode Island': 'RI',
    'South Carolina': 'SC',
    'South Dakota': 'SD',
    'Tennessee': 'TN',
    'Texas': 'TX',
    'Utah': 'UT',
    'Vermont': 'VT',
    'Virginia': 'VA',
    'Washington': 'WA',
    'West Virginia': 'WV',
    'Wisconsin': 'WI',
    'Wyoming': 'WY',
}

El siguiente paso es agregar una columna en el conjunto de datos que contenga abreviaturas. Podemos hacerlo asignando los valores en la columna Área a las claves en el diccionario us_state_abbrev. Los valores correspondientes se pueden agregar a la columna de abreviatura recién creada como se muestra a continuación:

1
df['abbrev'] = df['Area'].map(us_state_abbrev)

Ahora, si vuelve a imprimir la parte superior del marco de datos usando la función head(), verá la columna abbrev recién creada, como se muestra a continuación:

1
df.head()

La salida se ve así:

{.img-responsive}

Puede ver las abreviaturas de los estados en la columna abbrev. Es importante mencionar que la columna Área también tiene valores para todo el país. Sin embargo, el país tendrá una abreviatura correspondiente de NaN en la columna “abbrev” y, por lo tanto, se ignorará cuando trace el gráfico.

Ahora que hemos preprocesado nuestros datos, los siguientes pasos son sencillos. Primero, crearemos un diccionario de datos que contenga valores de nuestro conjunto de datos, como se muestra a continuación:

1
2
3
4
5
6
7
8
9
map_data = dict(type='choropleth',
            locations=df['abbrev'],
            locationmode='USA-states',
            colorscale='Reds',
            text=df['Area'],
            marker=dict(line=dict(color='rgb(255,0,0)', width=2)),
            z=df['2017'],
            colorbar=dict(title="GDP Per Capita - 2017")
           )

Puede ver que en el script anterior, para la clave ubicaciones estamos pasando la columna abbrev de nuestro conjunto de datos. Esto significa que la trama geográfica de todos los estados de los Estados Unidos se imprimirá en la pantalla.

De manera similar, para la clave texto estamos pasando la columna "Área" que contiene el nombre completo del estado. Finalmente, para la tecla z, pasamos el PIB per cápita del año 2017.

También es importante mencionar que aquí tenemos una nueva clave, es decir, marcador. Esto se utiliza para crear una frontera entre diferentes estados. Un valor RGB de 255,0,0 significa que el borde será rojo. Un ancho de 2 especifica que el ancho del borde es de 2 píxeles.

El siguiente paso es crear el diseño de nuestro mapa. El siguiente script hace eso:

1
2
3
4
5
map_layout = dict(title='USA States GDP Per Capita - 2017',
              geo=dict(scope='usa',
                         showlakes=True,
                         lakecolor='rgb(85,173,240)')
             )

Tenga en cuenta que en el script de arriba pasamos True para la clave showlakes, lo que significa que los lagos se mostrarán en el mapa y su color será azul claro según lo especificado por el valor RGB de rgb(85,173,240).

Finalmente, debe crear el objeto de gráfico y pasarle los diccionarios de datos y diseño, como hicimos en la última sección. Mira el siguiente guión:

1
map_actual = go.Figure(data=[map_data], layout=map_layout)

Como último paso, debemos llamar al método iplot() y pasarle nuestro objeto gráfico recién creado:

1
iplot(map_actual)

Una vez que ejecute el script anterior, verá un mapa de Estados Unidos con el PIB per cápita. Los estados de color más claro tienen un PIB menor que los de color más oscuro.

{.img-responsive}

Mapas geográficos para el mundo

En las secciones anteriores, vimos mapas gráficos de los Estados Unidos. En esta sección, veremos cómo trazar mapas geográficos para el mundo. El proceso sigue siendo más o menos similar. Como primer paso, crearemos un diccionario de datos, seguido del diccionario de diseño y el objeto gráfico. Finalmente, usaremos la función iplot() para trazar el gráfico.

El conjunto de datos

El conjunto de datos que vamos a utilizar contiene una población del mundo por país para los años 1960-2016. Trazaremos un mapa geográfico del mundo mostrando la población de cada país para el año 2016.

El conjunto de datos se puede descargar desde este Enlace Kaggle. El conjunto de datos se descargará en formato CSV.

El siguiente script importa el conjunto de datos y muestra sus primeras cinco filas usando el método head().

1
2
df = pd.read_csv(r'E:/world_pop.csv')
df.head()

La siguiente imagen contiene una captura de pantalla de la salida:

{.img-responsive}

Vamos a crear un diccionario de datos que almacenará la información sobre los datos que queremos trazar a partir del conjunto de datos de población que acabamos de cargar.

1
2
3
4
5
6
7
map_data = dict(
        type='choropleth',
        locations=df['Country Code'],
        z=df['2016'],
        text=df['Country'],
        colorbar={'title': 'World Population 2016'},
      )

En la secuencia de comandos anterior, puede ver que el único cambio que hicimos está en la clave ubicaciones; ahora estamos pasando el "Código de país" en lugar de las abreviaturas del estado. Este es un requisito obligatorio para trazar la trama geográfica del mundo. Para la clave texto, pasamos los valores de la columna "País" que contiene el nombre completo del país. De manera similar, para la clave z, pasamos los valores de la columna "2016" porque esta es la columna que contiene los valores de población para el año 2016.

El siguiente paso es crear un diccionario de diseño. Mira el siguiente guión:

1
2
3
4
map_layout = dict(
    title='World Population 2016',
    geo=dict(showframe=False)
)

En el diseño, el único parámetro que cambiamos es la tecla showFrame para el diccionario geo. Si esta clave se establece en False, el gráfico resultante no contiene un límite.

A continuación, debemos crear un objeto gráfico de Plotly y pasarle los datos y los diccionarios de diseño que creamos, como se muestra a continuación:

1
map_actual = go.Figure(data=[map_data], layout=map_layout)

Como último paso, necesitamos llamar a la función iplot() y pasarle el objeto gráfico que acabamos de crear.

La salida debería verse así:

En la salida, puede ver el mapa de todo el mundo junto con las densidades de población. Puede ver que el mapa de India y China es más oscuro en comparación con los otros países, ya que están mucho más poblados en comparación con los países europeos que están menos poblados. Si pasa el mouse sobre cualquier país, debería ver el nombre del país junto con la población total.

¿Busca una guía más detallada sobre Plotly y otras bibliotecas de visualización de Python? Consulte Visualización de datos en Python para obtener un gran recurso sobre 9 de las bibliotecas más populares, incluidas sus características, fortalezas y matices únicos.

Conclusión

Plotly es una biblioteca de Python extremadamente útil para la visualización interactiva de datos. En este artículo, vimos cómo podemos usar Plotly para trazar gráficas básicas como gráficas de dispersión, gráficas de líneas, histogramas y gráficas 3D básicas. También vimos cómo se puede usar Plotly para trazar gráficos geográficos usando el mapa de coropletas. Como ejemplo, trazamos parcelas geográficas para los Estados Unidos y para todo el mundo.

Le sugiero que explore la biblioteca de coropletas e intente practicar la creación de más gráficos geográficos, ya que hay muchas características para explorar. La documentación detallada de los mapas de coropletas está disponible en este enlace: https://plot.ly/python/choropleth-maps/.

Licensed under CC BY-NC-SA 4.0