Exponential values at X-axis in pyplot [duplicate] - python

I'm using Matplotlib in Python to plot simple x-y datasets. This produces nice-looking graphs, although when I "zoom in" too close on various sections of the plotted graph using the Figure View (which appears when you execute plt.show() ), the x-axis values change from standard number form (1050, 1060, 1070 etc.) to scientific form with exponential notation (e.g. 1, 1.5, 2.0 with the x-axis label given as +1.057e3).
I'd prefer my figures to retain the simple numbering of the axis, rather than using exponential form. Is there a way I can force Matplotlib to do this?

The formatting of tick labels is controlled by a Formatter object, which assuming you haven't done anything fancy will be a ScalerFormatterby default. This formatter will use a constant shift if the fractional change of the values visible is very small. To avoid this, simply turn it off:
plt.plot(arange(0,100,10) + 1000, arange(0,100,10))
ax = plt.gca()
ax.get_xaxis().get_major_formatter().set_useOffset(False)
plt.draw()
If you want to avoid scientific notation in general,
ax.get_xaxis().get_major_formatter().set_scientific(False)
Can control this with globally via the axes.formatter.useoffset rcparam.

You can use a simpler command to turn it off:
plt.ticklabel_format(useOffset=False)

You can use something like:
from matplotlib.ticker import ScalarFormatter, FormatStrFormatter
ax.xaxis.set_major_formatter(FormatStrFormatter('%.0f'))

Use the following command:
ax.ticklabel_format(useOffset=False, style='plain')
If you are using a subplot, you may experience the AttributeError: This method only works with the ScalarFormatter in which case you would add axis='y' like the below. You can change 'y' to the axis with the issues.
ax1.ticklabel_format(useOffset=False, style='plain', axis='y')
Source question and answer here. Note, the axis 'y' command use is hidden in the answer comments.

I have used below code before the graphs, and it worked seamless for me..
plt.ticklabel_format(style='plain')

Exactly I didn't want scientific numbers to be shown when I zoom in, and the following worked in my case too. I am using Lat/Lon in labeling where scientific form doesn't make sense.
plt.ticklabel_format(useOffset=False)

Related

Is there a way to change scale of y axis in python plot?

Currently i am able to generate this plot to calculate number of people using applications,
but i am getting y axis values as in decimals ,where in people cannot be in decimals.
how can i change this ?
df_pivot=pd.pivot_table(df_removed1,index=['Module'],columns=['Date'], aggfunc='size').plot(kind='bar',grid=True)
plt.xticks(weight='bold')
plt.xlabel(App_req,size="25",weight='bold')
plt.title(grph_title)
this is the code i am using to plot graph for my data
current output
You can try to give yticks() the integers generated by range():
plt.yticks(range(0,2))
Otherwise you can try:
from matplotlib.ticker import MaxNLocator
plt.yaxis.set_major_locator(MaxNLocator(integer=True))
You can try using
plt.set_yticks()
docs here: https://matplotlib.org/3.1.1/api/_as_gen/matplotlib.axes.Axes.set_yticks.html

How to remove scientific notation on bqplot?

I am using bqplot to create a live line graph on jupyter-notebook + VOILA
from bqplot import pyplot as plt2
import datetime
x_values = [] #array of datetimes
y_values = [] #array of 10+ digit numbers
plt2.show()
def functionThatIsCalledRepeatedly(x_val, y_val):
x_values.append(x_val)
y_values.append(y_val)
plt2.plot(x_values, y_values)
Part of the Resulting Plot
My question is, how do I remove the scientific notation from the y-axis. It's a simple task but I have tried a lot of things.
I tried using axes.tick_format property of the graph but I think that only works if you have axes objects which I cannot have because they require the mandatory Scale property which I cannot use because the graph is live and the x and y scales need to be generated/recalibrated while it runs.
I tried changing y_values.append(y_val) to y_values.append("{:.2f}".format(y_val)) but that converts to a string and bqplot doesn't process it as a number so it ends up with negative numbers on top of the 0 sometimes.
I tried converting to a numpy array and then doing np.set_printoptions(suppress=True) which (obviously) didn't work.
Basically tried a lot of things and I think it comes down to some bqplot property that may or may not exist. Have been stuck for a while. Thank you!
You can provide axes options with the tick format you want to the plot method:
plt2.plot(x_values, y_values, axes_options={
y=dict(tick_format='0.2f')
})
You can see examples of this axes_options (using a scatter plot, but that should work the same) in this notebook: https://github.com/bqplot/bqplot/blob/master/examples/Marks/Pyplot/Scatter.ipynb

How to change formatting of colorbar in combination with shrink

I am creating a colorbar for my figure like this:
def fmt(x, pos):
a='{:10.1f}'.format(x)
return a
fig.colorbar(CS, ax=ax,shrink=0.35,label=r'Electric Field/(V/$\mathrm{\AA}$)',format=ticker.FuncFormatter(fmt))
Creating the colorbar without the format command works just fine. However, I would like to control the number of decimal points in the colorbar labels. Adding the format command seems to not work in combination with shrink, since the labels are now shifted from the colorbar:
You are shifting the labels away from the colorbar yourself. So if you don't want that don't do it.
I.e. Using '{:10.1f}'.format(1) you tell the formatter to use 10 places before the decimal separator. You may leave out the 10 to get it to only use as many places as it needs,
'{:.1f}'.format(1)

matplotlib x-axis formatting if x-axis is pandas index

I'm using iPython notebook's %matplotlib inline and I'm having trouble formatting my plot.
As you can see, my first and last data point aren't showing up the way the other data points are showing up. I'd like to have the error bars visible and have the graph be "zoomed out" a bit.
df.plot(yerr=df['std dev'],color='b', ecolor='r')
plt.title('SpO2 Mean with Std Dev')
plt.xlabel('Time (s)')
plt.ylabel(SpO2)
I assume I have to use
matplotlib.pyplot.xlim()
but I'm not sure how to use it properly if my x-axis is a DataFrame index composed of strings:
index = ['-3:0','0:3','3:6','6:9','9:12','12:15','15:18','18:21','21:24']
Any ideas? Thanks!
You can see the usage of xlim here. Basically in this case if you ran plt.xlim() you would get(0.0, 8.0). As you have an index that uses text and not numbers the values for xlim are actually just the index of the entries in your index. So in this case you would just need to change the values by feeding in however many steps left and right you want your graph to take. For example:
plt.xlim(-1,len(df))
Would change this:
to this:
Hope that helps.

How to increase plot y-range iwith matplotlib? [duplicate]

I would like to plot a set of points using pyplot in matplotlib but have none of the points be on the edge of my axes. The autoscale (or something) sets the xlim and ylim such that often the first and last points lie at x = xmin or xmax making it difficult to read in some situations.
This is more often problematic with loglog() or semilog() plots because the autoscale would like xmin and xmax to be exact powers of ten, but if my data contains only three points, e.g. at xdata = [10**2,10**3,10**4] then the first and last points will lie on the border of the plot.
Attempted Workaround
This is my solution to add a 10% buffer to either side of the graph. But is there a way to do this more elegantly or automatically?
from numpy import array, log10
from matplotlib.pyplot import *
xdata = array([10**2,10**3,10**4])
ydata = xdata**2
figure()
loglog(xdata,ydata,'.')
xmin,xmax = xlim()
xbuff = 0.1*log10(xmax/xmin)
xlim(xmin*10**(-xbuff),xmax*10**(xbuff))
I am hoping for a one- or two-line solution that I can easily use whenever I make a plot like this.
Linear Plot
To make clear what I'm doing in my workaround, I should add an example in linear space (instead of log space):
plot(xdata,ydata)
xmin,xmax = xlim()
xbuff = 0.1*(xmax-xmin)
xlim(xmin-xbuff,xmax+xbuff))
which is identical to the previous example but for a linear axis.
Limits too large
A related problem is that sometimes the limits are too large. Say my data is something like ydata = xdata**0.25 so that the variance in the range is much less than a decade but ends at exactly 10**1. Then, the autoscale ylim are 10**0 to 10**1 though the data are only in the top portion of the plot. Using my workaround above, I can increase ymax so that the third point is fully within the limits but I don't know how to increase ymin so that there is less whitespace at the lower portion of my plot. i.e., the point is that I don't always want to spread my limits apart but would just like to have some constant (or proportional) buffer around all my points.
#askewchan I just succesfully achieved how to change matplotlib settings by editing matplotlibrc configuration file and running python directly from terminal. Don't know the reason yet, but matplotlibrc is not working when I run python from spyder3 (my IDE). Just follow steps here matplotlib.org/users/customizing.html.
1) Solution one (default for all plots)
Try put this in matplotlibrc and you will see the buffer increase:
axes.xmargin : 0.1 # x margin. See `axes.Axes.margins`
axes.ymargin : 0.1 # y margin See `axes.Axes.margins`
Values must be between 0 and 1.
Obs.: Due to bugs, scale is not correctly working yet. It'll be fixed for matplotlib 1.5 (mine is 1.4.3 yet...). More info:
axes.xmargin/ymargin rcParam behaves differently than pyplot.margins() #2298
Better auto-selection of axis limits #4891
2) Solution two (individually for each plot inside the code)
There is also the margins function (for put directly in the code). Example:
import numpy as np
from matplotlib import pyplot as plt
t = np.linspace(-6,6,1000)
plt.plot(t,np.sin(t))
plt.margins(x=0.1, y=0.1)
plt.savefig('plot.png')
Obs.: Here scale is working (0.1 will increase 10% of buffer before and after x-range and y-range).
A similar question was posed to the matplotlib-users list earlier this year. The most promising solution involves implementing a Locator (based on MaxNLocator in this case) to override MaxNLocator.view_limits.

Categories

Resources