Using the following code:-
fig=plt.figure()
#ax = fig.add_subplot(111)
ax=plt.axes()
font0 = FontProperties()
outgrid=[[x*y for x in range(testXaxis)] for y in range (levIndRange)]
vmin=0
vmax=testXaxis*levIndRange
height = [v*1000.5 for v in range (levMaxInd)]
colours='terrain'
cmap=plt.cm.get_cmap(colours)
norm=matplotlib.colors.Normalize(clip=False,vmin=vmin,vmax=vmax)
print 'vmax = ',vmax
m=plt.cm.ScalarMappable(cmap=cmap,norm=norm)
m.set_array(outgrid)
plt.imshow(np.flipud(outgrid),cmap=cmap, norm=norm, aspect=stretch)
#ax.imshow(np.flipud(outgrid),cmap=cmap, norm=norm, aspect=stretch)
ax.yaxis.set_major_formatter(FormatStrFormatter('%.0f'))
#plt.axis.YAxis.set_major_formatter(FormatStrFormatter('%.0f')) # 'module' object has no attribute 'set_major_formatter'
plt.yticks([s for s in range(0,levIndRange,levParInt)],[height[v] for v in range(levMinInd-1,levMaxInd-1,levParInt)])
plt.xticks([1,3,5,7,9,11,13,15,17,19])
#ax.xaxis.set_ticks([1,3,5,7,9,11,13,15,17,19])
#ax.yaxis.set_ticks([height[v] for v in range(levMinInd-1,levMaxInd-1,levParInt)]) # This one line makes the plot collapse
plt.ylabel(yLabel)
plt.xlabel(xLabel)
I get the following plot, which is fine, but I want to change the floating point precision on the y-axis:-
So, when I try to alter the precision on the y-axis using set_major_formatter and the following lines instead of plot.yticks :-
ax.yaxis.set_major_formatter(FormatStrFormatter('%.0f'))
ax.xaxis.set_ticks([1,3,5,7,9,11,13,15,17,19])
ax.yaxis.set_ticks([height[v] for v in range(levMinInd-1,levMaxInd-1,levParInt)]) # This one line makes the plot collapse
... the plot disappears:-
How can I alter the precision without losing the plot?
Any help gratefully received.
Thanks
I am answering rather than editing because I have solved the lost plot problem, and that might be a help to someone else. The solution is to move the plt.imshow line AFTER the ax.yaxis.set_ticks line. However, I am still not getting the expected Y axis ticks with no decimal point.
The first block of code below produces a plot with Y ticks: 0.0,1000.5,2001.0,3001.5,4002.0
import matplotlib
import matplotlib.pyplot as plt
outgrid=[[x*y for x in range(4)] for y in range (5)]
height = [v*1000.5 for v in range (5)]
cmap=plt.cm.get_cmap('terrain')
norm=matplotlib.colors.Normalize(clip=False)
m=plt.cm.ScalarMappable(cmap=cmap,norm=norm)
m.set_array(outgrid)
plt.imshow(outgrid,cmap=cmap, norm=norm, aspect=0.5)
plt.yticks([s for s in range(5)],[height[t] for t in range(5)])
plt.show()
This second block of code tries to format these ticks with no decimal point but just produces one Y tick of 0
import matplotlib
import matplotlib.pyplot as plt
from matplotlib.ticker import FormatStrFormatter
ax=plt.axes()
outgrid=[[x*y for x in range(4)] for y in range (5)]
height = [v*1000.5 for v in range (5)]
cmap=plt.cm.get_cmap('terrain')
norm=matplotlib.colors.Normalize(clip=False)
m=plt.cm.ScalarMappable(cmap=cmap,norm=norm)
m.set_array(outgrid)
ax.yaxis.set_major_formatter(FormatStrFormatter('%.0f'))
ax.yaxis.set_ticks([height[t] for t in range(5)])
plt.imshow(outgrid,cmap=cmap, norm=norm, aspect=0.5)
plt.show()
Related
I'm having the hardest time achieving the following:
I need to stop the x labels from showing after the vertical dashed line seen in the image:
Basically, I want to eliminate the 5 in this example.
I successfully stopped the ticks with the condition placed on "set_ticks", but the labels keep displaying.
My code:
ax2 = plt.subplot()
ax2.pcolormesh(xext, ye, Zext, cmap='hot')
ax2.set_xticks([a for a in xext if a<myval], minor=True)
ax2.axvline(myval, linestyle='--', color='white')
plt.show()
A solution like writing a list of [1,2,3,4] would not help me.
I need this to work for a large number of examples where all I know is the limit value, or myval from the code above.
(I am restating and narrowing down a question I posted before, now deleted.)
You only changed the minor ticks (the very short lines) on the x-axis. The major ticks also should be changed. ax.get_xticks() gives a list of the current ticks, which you can filter and apply again:
import matplotlib.pyplot as plt
import numpy as np
fig, ax2 = plt.subplots()
xext = np.arange(9.1, step=.1)
ye = np.arange(6)
zext = np.random.randn(len(ye) - 1, len(xext) - 1).cumsum(axis=1)
zext -= zext.mean(axis=1, keepdims=True)
ax2.pcolormesh(xext, ye, zext, cmap='hot')
myval = 6.28
ax2.set_xticks([a for a in xext if a < myval], minor=True)
xticks = ax2.get_xticks()
ax2.set_xticks([a for a in xticks if a < myval])
ax2.axvline(myval, linestyle='--', color='white')
plt.show()
This excerpt from my code changes the value of the y axis labels from exponential to millions. Problem is it creates 2 figures. The first one is an x and y axis with no plot (and the scale of the x axis is used for the y axis as well), and then the 2nd figure is exactly what I want. It is a double bar graph.
I am guessing it has something to do with using f.plot.bar instead of plt.bar but I am not sure. I just want to get rid of the first figure than all will be well.
from matplotlib.ticker import FuncFormatter
def millions(x, pos):
'The two args are the value and tick position'
return '%1.1fM' % (x*1e-6)
formatter = FuncFormatter(millions)
fig, ax = plt.subplots()
ax = tempg.plot.bar(y=['Republican2016Votes', 'Democrat2016Votes'], rot=0,
color = ['DarkRed','Blue'])
ax.yaxis.set_major_formatter(formatter)
plt.show()
I can't get any tick marks to appear when I have a narrow range of data and log formatting. I found a similar problem that talked about forcing a minimum number of ticks and tried that solution, but it did not seem to help.
What I want to do is have the Y range be automatically expanded until at least two ticks can be included, including one major tick (so it gets a label). I can't do anything to manual or custom because a lot of different data goes through this routine and it is only rarely that the range is so tight that no labels appear.
Here is an example that preserves as much of my local environment as possible:
import matplotlib
import numpy as np
import pylab as plt
fig=plt.figure(figsize=(15, 20))
locmin = matplotlib.ticker.LogLocator(base=10.0,subs=(.1,.2,.3,.4,.5,.6,.7,.8,.9),numticks=15)
ax6 = plt.subplot(616)
plt.plot(np.random.random(1000)*4+14, 'b')
plt.plot(np.random.random(1000)*4+14, 'r')
plt.minorticks_on()
plt.ylabel('Y')
plt.yscale('log')
ax6.yaxis.set_minor_locator(locmin)
ax6.yaxis.set_minor_formatter(matplotlib.ticker.NullFormatter())
plt.show()
The result is this plot here, which has no Y labels...
You can get the array of major_ticks and minor_ticklocs. Then find the bounds for the given scaled y limits. Then you can explicitly set the ylim of the plot. Since the values in the example scales between 10 and 20, the 10 from major_ticks and 20 from minor_ticks are shown. Consider below code:
import matplotlib
import numpy as np
import pylab as plt
fig=plt.figure(figsize=(15, 20))
locmin = matplotlib.ticker.LogLocator(base=10.0,subs=(.1,.2,.3,.4,.5,.6,.7,.8,.9),numticks=15)
ax6 = plt.subplot(616)
plt.plot(np.random.random(1000)*4+14, 'b')
plt.plot(np.random.random(1000)*4+14, 'r')
plt.minorticks_on()
plt.ylabel('Y')
plt.yscale('log')
ax6.yaxis.set_minor_locator(locmin)
ax6.yaxis.set_minor_formatter(matplotlib.ticker.NullFormatter())
plt.tick_params(axis='y', which='minor')
ax6.yaxis.set_minor_formatter(matplotlib.ticker.FormatStrFormatter("%.1f"))
tickArr = np.concatenate((plt.yticks()[0], ax6.yaxis.get_minorticklocs()))
ylim_min = tickArr[tickArr < plt.ylim()[0]].max()
ylim_max = tickArr[tickArr > plt.ylim()[1]].min()
plt.ylim([ylim_min, ylim_max])
plt.show()
I am having an issue plotting after a date has been plotted. the code is the following:
import matplotlib.pyplot as plt
from matplotlib import style
x = [735412.0, 735503.0, 735594.0, 735685.0]
y =['0.0', '16961000000.0', '29030000000.0', '32504000000.0']
z = ['100000', '200000000000', '3000000000000', '400000000000']
# plt.plot_date(x, y, marker='o', linestyle='-', color='b')
plt.plot(y,z) # this does not print if above line is uncommented
plt.gcf().autofmt_xdate() # turns bottom dates at angle
plt.show()
What am I doing wrong?
Thanks!
L
First of all, your "numbers" in y are actually strings. You would need to convert them to float using np.array(y, float) to use them on an axis.
But did you really intend to plt.plot(y,z) in the same figure as the others? The values in y are not dates/times of any kind, so probably not.
I suspect this should be a new figure, so you need to start a new figure with plt.figure() before you plot y vs z:
plt.figure()
plt.plot(y,z)
and drop the plt.gcf().autofmt_xdate() after that.
This code:
import numpy as np
import matplotlib.pyplot as plt
letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
x = range(26)
v = np.random.random(26)
fig = plt.figure()
ax = fig.add_subplot(111)
ax.bar(x, v, width=0.8, align='center')
ax.set_xticks(x)
ax.set_xticklabels(letters)
plt.savefig('so.eps')
Generates the figure below:
As you can see, the 'Q' is not aligned with the baseline properly and looks wrong.
Can anyone shed any light on this? If it's a bug in Matplotlib, is there a hack to get round it (e.g. by realigning a single xtick label)?
I have text.usetex : True in my matplotlibrc file, and the problem only seems to show when I save the figure as eps.