Configuración de ambos ejes logarítmicos en diagtwig de barras matploblib

Ya he agrupado los datos para trazar un histogtwig. Por esta razón estoy usando la función plt.bar() . Me gustaría establecer ambos ejes en la ttwig a una escala logarítmica.

Si configuro plt.bar(x, y, width=10, color='b', log=True) que me permite configurar el eje y en el registro pero no puedo configurar el logarítmico del eje x. He intentado plt.xscale('log') desafortunadamente esto no funciona bien. Las marcas del eje x desaparecen y los tamaños de las barras no tienen el mismo ancho.

introduzca la descripción de la imagen aquí

Apreciaría cualquier ayuda.

Por defecto, las barras de un gráfico de bar tienen un ancho de 0.8. Por lo tanto, aparecen más grandes para valores x más pequeños en una escala logarítmica. Si en lugar de especificar un ancho constante, uno usa la distancia entre los bordes de la bandeja y lo suministra al argumento de width , las barras tendrán el ancho correcto. También sería necesario establecer la align en "edge" para que esto funcione.

 import matplotlib.pyplot as plt import numpy as np; np.random.seed(1) x = np.logspace(0, 5, num=21) y = (np.sin(1.e-2*(x[:-1]-20))+3)**10 fig, ax = plt.subplots() ax.bar(x[:-1], y, width=np.diff(x), log=True,ec="k", align="edge") ax.set_xscale("log") plt.show() 

introduzca la descripción de la imagen aquí

No puedo reproducir ticklabels faltantes para una escala logarítmica. Esto puede deberse a algunas configuraciones en el código que no se muestran en la pregunta o al hecho de que se usa una versión más antigua de matplotlib. El ejemplo aquí funciona bien con matplotlib 2.0.

Si el objective es tener barras de igual ancho, asumiendo que los puntos de datos no son equidistantes, entonces la solución más adecuada es establecer el ancho como plt.bar(x, y, width=c*np.array(x), color='b', log=True) para una constante c apropiada para la ttwig. La alineación puede ser cualquier cosa.

Sé que es una pregunta muy antigua y es posible que la hayas resuelto, pero he llegado a este post porque estaba con algo como esto pero en el eje y, y logro resolverlo solo usando ax.set_ylim(df['my data'].min()+100, df['my data'].max()+100) . En el eje y tengo cierta información sensible que creo que la mejor manera era mostrarla en la escala de registro, pero cuando configuré la escala de registro no pude ver los números propiamente dichos (como esta publicación en el eje x), así que solo dejo la idea de uso registra y usa el mínimo y máximo argumento. Establece la escala de mi gráfico de manera muy similar a como registro. Todavía estoy buscando otra manera de no tener que usar ese – + 100 en set_ylim.

Si bien esto no usa realmente pyplot.bar, creo que este método podría ser útil para lograr lo que el OP está tratando de hacer. Descubrí que esto es más fácil que intentar calibrar el ancho como una función de la escala de registro, aunque son más pasos. Cree una colección de líneas cuyo ancho sea independiente de la escala del gráfico.

 import matplotlib.pyplot as plt import numpy as np import matplotlib.collections as coll #Generate data and sort into bins a = np.random.logseries(0.5, 1000) hist, bin_edges = np.histogram(a, bins=20, density=False) x = bin_edges[:-1] # remove the top-end from bin_edges to match dimensions of hist lines = [] for i in range(len(x)): pair=[(x[i],0), (x[i], hist[i])] lines.append(pair) linecoll = coll.LineCollection(lines, linewidths=10, linestyles='solid') fig, ax = plt.subplots() ax.add_collection(linecoll) ax.set_xscale("log") ax.set_yscale("log") ax.set_xlim(min(x)/10,max(x)*10) ax.set_ylim(0.1,1.1*max(hist)) #since this is an unweighted histogram, the logy doesn't make much sense. 

Parcela resultante – sin lujos

Un inconveniente es que las “barras” se centrarán, pero esto podría cambiarse compensando los valores de x en la mitad del valor del ancho de línea … Creo que sería
x_new = x + (linewidth / 2) * 10 ** round (np.log10 (x), 0).