xticks pyplot font python matplotlib parallel-coordinates

python - font - pyplot title



Parcela de coordenadas paralelas en Matplotlib (4)

Los datos bidimensionales y tridimensionales se pueden ver de forma relativamente directa utilizando tipos de gráficos tradicionales. Incluso con datos de cuatro dimensiones, a menudo podemos encontrar una manera de mostrar los datos. Las dimensiones superiores a cuatro, sin embargo, se vuelven cada vez más difíciles de mostrar. Afortunadamente, las gráficas de coordenadas paralelas proporcionan un mecanismo para ver resultados con dimensiones superiores.

Varios paquetes de trazado proporcionan gráficas de coordenadas paralelas, como Matlab , R , VTK tipo 1 y VTK tipo 2 , pero no veo cómo crear una usando Matplotlib.

  1. ¿Hay un gráfico de coordenadas paralelas incorporado en Matplotlib? Ciertamente no veo uno en la galería .
  2. Si no hay un tipo incorporado, ¿es posible construir un gráfico de coordenadas paralelas utilizando las características estándar de Matplotlib?

Editar :

En base a la respuesta proporcionada por Zhenya a continuación, desarrollé la siguiente generalización que admite un número arbitrario de ejes. Siguiendo el estilo de trama del ejemplo que publiqué en la pregunta original anterior, cada eje obtiene su propia escala. Lo logré normalizando los datos en cada punto del eje y haciendo que los ejes tengan un rango de 0 a 1. Luego regreso y aplico etiquetas a cada marca que da el valor correcto en esa intersección.

La función funciona al aceptar un conjunto de datos iterable. Cada conjunto de datos se considera un conjunto de puntos donde cada punto se encuentra en un eje diferente. El ejemplo en __main__ toma números aleatorios para cada eje en dos conjuntos de 30 líneas. Las líneas son aleatorias dentro de los rangos que causan la agrupación de líneas; un comportamiento que quería verificar

Esta solución no es tan buena como una solución integrada, ya que tiene un comportamiento extraño en el mouse y falsifico los rangos de datos a través de las etiquetas, pero hasta que Matplotlib agregue una solución integrada, es aceptable.

#!/usr/bin/python import matplotlib.pyplot as plt import matplotlib.ticker as ticker def parallel_coordinates(data_sets, style=None): dims = len(data_sets[0]) x = range(dims) fig, axes = plt.subplots(1, dims-1, sharey=False) if style is None: style = [''r-'']*len(data_sets) # Calculate the limits on the data min_max_range = list() for m in zip(*data_sets): mn = min(m) mx = max(m) if mn == mx: mn -= 0.5 mx = mn + 1. r = float(mx - mn) min_max_range.append((mn, mx, r)) # Normalize the data sets norm_data_sets = list() for ds in data_sets: nds = [(value - min_max_range[dimension][0]) / min_max_range[dimension][2] for dimension,value in enumerate(ds)] norm_data_sets.append(nds) data_sets = norm_data_sets # Plot the datasets on all the subplots for i, ax in enumerate(axes): for dsi, d in enumerate(data_sets): ax.plot(x, d, style[dsi]) ax.set_xlim([x[i], x[i+1]]) # Set the x axis ticks for dimension, (axx,xx) in enumerate(zip(axes, x[:-1])): axx.xaxis.set_major_locator(ticker.FixedLocator([xx])) ticks = len(axx.get_yticklabels()) labels = list() step = min_max_range[dimension][2] / (ticks - 1) mn = min_max_range[dimension][0] for i in xrange(ticks): v = mn + i*step labels.append(''%4.2f'' % v) axx.set_yticklabels(labels) # Move the final axis'' ticks to the right-hand side axx = plt.twinx(axes[-1]) dimension += 1 axx.xaxis.set_major_locator(ticker.FixedLocator([x[-2], x[-1]])) ticks = len(axx.get_yticklabels()) step = min_max_range[dimension][2] / (ticks - 1) mn = min_max_range[dimension][0] labels = [''%4.2f'' % (mn + i*step) for i in xrange(ticks)] axx.set_yticklabels(labels) # Stack the subplots plt.subplots_adjust(wspace=0) return plt if __name__ == ''__main__'': import random base = [0, 0, 5, 5, 0] scale = [1.5, 2., 1.0, 2., 2.] data = [[base[x] + random.uniform(0., 1.)*scale[x] for x in xrange(5)] for y in xrange(30)] colors = [''r''] * 30 base = [3, 6, 0, 1, 3] scale = [1.5, 2., 2.5, 2., 2.] data.extend([[base[x] + random.uniform(0., 1.)*scale[x] for x in xrange(5)] for y in xrange(30)]) colors.extend([''b''] * 30) parallel_coordinates(data, style=colors).show()

Editar 2:

Aquí hay un ejemplo de lo que sale del código anterior al trazar los datos de Fisher Iris . No es tan bonito como la imagen de referencia de Wikipedia, pero es aceptable si todo lo que tienes es Matplotlib y necesitas tramas multidimensionales.



Estoy seguro de que hay una mejor manera de hacerlo, pero aquí hay uno rápido y sucio (uno muy sucio):

#!/usr/bin/python import numpy as np import matplotlib.pyplot as plt import matplotlib.ticker as ticker #vectors to plot: 4D for this example y1=[1,2.3,8.0,2.5] y2=[1.5,1.7,2.2,2.9] x=[1,2,3,8] # spines fig,(ax,ax2,ax3) = plt.subplots(1, 3, sharey=False) # plot the same on all the subplots ax.plot(x,y1,''r-'', x,y2,''b-'') ax2.plot(x,y1,''r-'', x,y2,''b-'') ax3.plot(x,y1,''r-'', x,y2,''b-'') # now zoom in each of the subplots ax.set_xlim([ x[0],x[1]]) ax2.set_xlim([ x[1],x[2]]) ax3.set_xlim([ x[2],x[3]]) # set the x axis ticks for axx,xx in zip([ax,ax2,ax3],x[:-1]): axx.xaxis.set_major_locator(ticker.FixedLocator([xx])) ax3.xaxis.set_major_locator(ticker.FixedLocator([x[-2],x[-1]])) # the last one # EDIT: add the labels to the rightmost spine for tick in ax3.yaxis.get_major_ticks(): tick.label2On=True # stack the subplots together plt.subplots_adjust(wspace=0) plt.show()

Esto se basa esencialmente en una (mucho más agradable) de Joe Kingon, Python / Matplotlib. ¿Hay alguna manera de hacer un eje discontinuo? . También es posible que desee echar un vistazo a la otra respuesta a la misma pregunta.

En este ejemplo, ni siquiera intento escalar las escalas verticales, ya que depende de qué es exactamente lo que estás tratando de lograr.

EDITAR: Aquí está el resultado


Tenga en cuenta: cuando se utilizan pandas (como sugiere theta), no hay forma de escalar los ejes de forma independiente.

La razón por la que no puede encontrar los diferentes ejes verticales es porque no hay ninguno. Nuestras coordenadas paralelas están "falsificando" los otros dos ejes simplemente dibujando una línea vertical y algunas etiquetas.

https://github.com/pydata/pandas/issues/7083#issuecomment-74253671

Lo siento, no puedo añadir esto como comentario directo (reputación <50)


pandas tiene un contenedor de coordenadas paralelas:

import pandas import matplotlib.pyplot as plt from pandas.tools.plotting import parallel_coordinates data = pandas.read_csv(r''C:/Python27/Lib/site-packages/pandas/tests/data/iris.csv'', sep='','') parallel_coordinates(data, ''Name'') plt.show()

Código fuente, cómo lo hicieron: plotting.py#L494