Matplotlib imshow ticks are wrong with negative values - python

import matplotlib.pyplot as plt
import numpy as np
a = np.random.randn(5,5)
plt.imshow(a)
plt.xticks(range(5))
plt.yticks([i-2 for i in range(5)])
plt.show()
results in
??
Also imagine I had 500 instead of 5 ticks, how could I pass the ticks but have less be displayed (for example every 10th)?

Use the extent parameter, and no need to use xticks or yticks:
plt.imshow(a, extent=(-0.5, 4.5, -2.5, 2.5))
Output:
Use MultipleLocator for your second question:
from matplotlib.ticker import MultipleLocator
a = np.random.randn(500,500)
fig, ax = plt.subplots(figsize=(10, 10))
ax.imshow(a, extent=(-0.5, 500.5, -250.5, 250.5))
ax.xaxis.set_major_locator(MultipleLocator(25))
ax.yaxis.set_major_locator(MultipleLocator(25))
Output:

Related

Matplotlib: Is there a way to get a colorbar axis from a parent axis?

I am doing a plot something like this:
import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np
fig = plt.gcf()
ax = plt.gca()
ax.pcolormesh(np.random.rand(10, 10))
fig.colorbar(mpl.cm.ScalarMappable(), ax=ax)
The last line adds a colorbar and a second axis
fig.axes
>>> [<AxesSubplot:>, <AxesSubplot:label='<colorbar>'>]
My question:
Is there any relation between the two axes that can be used to get the axis of the colorbar (second in the list above) using only the axis returned by ax = plt.gca() (first returned in the list above)?
As far as I know, if you define pcolormesh and colorbar that way, no.
Anyway, you can define an ax for the pcolormesh and a cax for the colorbar beforehand. Then you can pass cax as parameter to matplotlib.pyplot.colorbar. In this way you can access to both axis ax and cax as you need.
import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np
grid_kws = {'width_ratios': (0.9, 0.05), 'wspace': 0.2}
fig, (ax, cax) = plt.subplots(1, 2, gridspec_kw = grid_kws, figsize = (10, 8))
ax.pcolormesh(np.random.rand(10, 10))
plt.colorbar(mpl.cm.ScalarMappable(), cax=cax)
plt.show()
In general, focusing on your code:
import matplotlib as mpl
import matplotlib.pyplot as plt
import numpy as np
fig = plt.gcf()
ax = plt.gca()
ax.pcolormesh(np.random.rand(10, 10))
fig.colorbar(mpl.cm.ScalarMappable(), ax=ax)
starting from ax, you can get its figure with ax.figure. From there, you can get the list of all figure axes with ax.figure.axes. So, if you want to get colobar's axis using only pcolormesh' axis, you should use:
ax.figure.axes[1]
The parent figure, as far as I know, is the only relation between the two axes.

Seaborn Adjusting Markers

As you can see here, the X axis labels here are quite unreadable. This will happen regardless of how I adjust the figure size. I'm trying to figure out how to adjust the labeling so that it only shows certain points. The X axis are all numerical between -1 to 1, and I think it would be nice and more viewer friendly to have labels at -1, -.5, 0, .5 and 1.
Is there a way to do this? Thank you!
Here's my code
sns.set(rc={'figure.figsize':(20,8)})
ax = sns.countplot(musi['Positivity'])
ax.set_xticklabels(ax.get_xticklabels(), rotation=40, ha='right')
plt.tight_layout()
plt.show()
Basically seaborn is wrapper on matplotlib. You can use matplotlib ticker function to do a Job. Refer the below example.
Let's Plots tick every 1 spacing.
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
import seaborn as sns
sns.set_theme(style="whitegrid")
x = [0,5,9,10,15]
y = [0,1,2,3,4]
tick_spacing = 1
fig, ax = plt.subplots(1,1)
sns.lineplot(x, y)
ax.xaxis.set_major_locator(ticker.MultipleLocator(tick_spacing))
plt.show()
Now Let's plot ticks every 5 ticks.
import matplotlib.pyplot as plt
import matplotlib.ticker as ticker
import seaborn as sns
sns.set_theme(style="whitegrid")
x = [0,5,9,10,15]
y = [0,1,2,3,4]
tick_spacing = 5
fig, ax = plt.subplots(1,1)
sns.lineplot(x, y)
ax.xaxis.set_major_locator(ticker.MultipleLocator(tick_spacing))
plt.show()
P.S.: This solution give you explicit control of the tick spacing via the number given to ticker.MultipleLocater(), allows automatic limit determination, and is easy to read later.

Setting the size of the scale factor on Matplotlib with very large/small scales

The following code:
import matplotlib.pyplot as plt
import numpy as np
r = 1e-20
t = np.linspace(0, 2*np.pi, 200)
fig, ax = plt.subplots()
ax.tick_params(axis='x', labelsize=8)
ax.plot(r*np.cos(t), r*np.sin(t))
Produces this:
Look at the "1e-20" on the x-axis. It isn't scaling with the rest of the tick labels. How do I change its fontsize?
Unfortunately, you will need to change the fontsize for the offset text separately:
ax.xaxis.offsetText.set_fontsize(8)

Removing all but one tick on x-axis

I have a graph that I would tick to remove all ticks and their corresponding labels bar the first tick and label on the x-axis. How would I go about this?
import pylab
import numpy as np
import matplotlib.pyplot as plt
a=np.linspace(0,10,10000)
print a
def f(x):
return 1/(1-(x**2)*np.log((1/(x**2)+1)))
b=f(a)
fig, ax = plt.subplots(1)
ax.plot(b,a)
pylab.xlim(0.5, 5)
pylab.ylim(0, 1.5)
fig.show()
you can use ax.set_xticks([1]) to set just one xtick at 1,0.
Also, there's no need to import both pylab and matplotlib.pyplot. The recommended way now is to import matplotlib.pyplot and use all the Axes methods. E.g., you can use ax.set_xlim instead of pylab.xlim.
Here's your full script and output plot:
import numpy as np
import matplotlib.pyplot as plt
a=np.linspace(0,10,10000)
print a
def f(x):
return 1/(1-(x**2)*np.log((1/(x**2)+1)))
b=f(a)
fig, ax = plt.subplots(1)
ax.plot(b,a)
ax.set_xlim(0.5, 5)
ax.set_ylim(0, 1.5)
ax.set_xticks([1])
plt.show()

Python - matplotlib modify xticks for a "loglog" plot

I am plotting in log scale for each axis, but I don't want scientific notation for the x axis, so I modified it as follows:
from matplotlib import pyplot as plt
from matplotlib.ticker import FormatStrFormatter
a = np.array([10.**(-2), 10.**(-3), 5.*10**(-3),10.**(-4), 10.**(-6), 10.**(-7)])
b = np.array([16, 12.5, 14.5, 9.5, 8., 7.5])
axes = plt.subplot(111)
plt.loglog(a,b, 'k.',markersize=10,markerfacecolor='None',label='')
plt.ylim(10**(-6),10**(-1))
plt.xlim(5,30)
plt.subplots_adjust(left=0.15)
plt.legend(loc=2)
axes.xaxis.set_minor_formatter(FormatStrFormatter("%.0f"))
plt.show()
But, as you can see in the picture below, there is 10 in scientific notation amongst the x axis labels... I don't know how to suppress it and just have 10...
You can use the ScalarFormatter from matplotlib.ticker
import matplotlib.pyplot as plt
from matplotlib.ticker import ScalarFormatter
fig = plt.figure()
ax = fig.add_subplot(111)
ax.semilogx(range(100))
ax.set_xscale('log')
ax.set_yscale('log')
ax.xaxis.set_major_formatter(ScalarFormatter())
#ax.yaxis.set_major_formatter(ScalarFormatter()) # for the y axis
fig.show()

Categories

Resources