This question already has answers here:
Modify tick label text
(13 answers)
Closed 3 years ago.
I have the following piece of code which creates a simple plot with matplotlib (python 3.6.9, matplotlib 3.1.2, Mac Mojave):
import numpy as np
import matplotlib.pyplot as plt
plt.imshow(np.random.random((50,50)))
plt.show()
The created plot is as expected:
Now, in order to relabel the xtick/ytick labels I am using the following code
import numpy as np
import matplotlib.pyplot as plt
plt.imshow(np.random.random((50,50)));
ticks, labels = plt.xticks()
labels[1] = '22'
plt.xticks(ticks, labels)
plt.show()
where I expect the second label to be replaced by '22', but everything else stays the same. However, I get the following plot instead:
There is some unexpected white area in the left part of the plot
All the other labels have vanished.
How to do it correctly?
Just as a reminder: I want to get the exact same result as the original image (first plot), ONLY with one of the lables changed.
This question has been asked before, one example is here. But the answer does not seem to work. Here is the code
import numpy as np
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
plt.imshow(np.random.random((50,50)))
labels = [item.get_text() for item in ax.get_xticklabels()]
labels[1] = 'Test'
ax.set_xticklabels(labels)
plt.show()
which creates an image as follows:
which does not show the white area anymore, but still the other labels are not shown.
Create axes using subplots, so that you can have set_xticklabels method, so you can update the labels.
You need to use, canvas.draw() to get the values.
import numpy as np
import matplotlib.pyplot as plt
fig,ax = plt.subplots()
ax.imshow(np.random.random((50,50)));
fig.canvas.draw()
#labels = ['-10','0','22','20','30','40'] or
labels[2]=22
ax.set_xticklabels(labels)
plt.show()
Output:
Hope this is what you need!
Related
I'm experimenting with seaborn and have a question about specifying axes properties. In my code below, I've taken two approaches to creating a heatmap of a matrix and placing the results on two sets of axes in a figure.
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
A=np.random.randn(4,4)
labels=['a','b','c','d']
fig, ax = plt.subplots(2)
sns.heatmap(ax =ax[0], data = A)
ax[0].set_xticks(range(len(labels)))
ax[0].set_xticklabels(labels,fontsize=10,rotation=45)
ax[0].set_yticks(range(len(labels)))
ax[0].set_yticklabels(labels,fontsize=10,rotation=45)
ax[1].set_xticks(range(len(labels)))
ax[1].set_xticklabels(labels,fontsize=10,rotation=45)
ax[1].set_yticks(range(len(labels)))
ax[1].set_yticklabels(labels,fontsize=10,rotation=45)
sns.heatmap(ax =ax[1], data = A,xticklabels=labels, yticklabels=labels)
plt.show()
The resulting figure looks like this:
Normally, I would always take the first approach of creating the heatmap and then specifying axis properties. However, when creating an animation (to be embedded on a tkinter canvas), which is what I'm ultimately interested in doing, I found such an ordering in my update function leads to "flickering" of axis labels. The second approach will eliminate this effect, and it also centers the tickmarks within squares along the axes.
However, the second approach does not rotate the y-axis tickmark labels as desired. Is there a simple fix to this?
I'm not sure this is what you're looking for. It looks like you create your figure after you change the yticklabels. so the figure is overwriting your yticklabels.
Below would fix your issue.
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
A=np.random.randn(4,4)
labels=['a','b','c','d']
fig, ax = plt.subplots(2)
sns.heatmap(ax =ax[0], data = A)
ax[0].set_xticks(range(len(labels)))
ax[0].set_xticklabels(labels,fontsize=10,rotation=45)
ax[0].set_yticks(range(len(labels)))
ax[0].set_yticklabels(labels,fontsize=10,rotation=45)
ax[1].set_xticks(range(len(labels)))
ax[1].set_xticklabels(labels,fontsize=10,rotation=45)
ax[1].set_yticks(range(len(labels)))
sns.heatmap(ax =ax[1], data = A,xticklabels=labels, yticklabels=labels)
ax[1].set_yticklabels(labels,fontsize=10,rotation=45)
plt.show()
This question already has answers here:
plot several image files in matplotlib subplots
(2 answers)
Closed 1 year ago.
I am producing a lot of figures with Matplotlib.pyplot (spatial data) and saving them as png's. I would like to be able to first make the figures (in loops), and then choose a few to put together in a multiple-panel figure, using Matplotlib.
I suppose this would mean re-opening the existing png's, and then putting them together using pyplot.subplots(), but I can't figure out a way to do it.
Does anybody have an idea?
Thanks!
Here's an example of what I think you mean:
import matplotlib.pyplot as plt
from matplotlib import image
import numpy as np
# initialise grid of axes
fig, axes = plt.subplots(2,2)
axes = axes.ravel()
# create fake data
img = [
'01-img.png',
'02-img.png',
'03-img.png',
'04-img.png',
]
# iterate over axes
for i, ax in enumerate(axes):
im = image.imread(img[i])
ax.imshow(im)
plt.show()
Use image.imread to load the image into a plottable form, then use ax.imshow to plot the pixels on the axis
This question already has answers here:
Change x-axis ticks to custom strings [duplicate]
(2 answers)
Closed 3 years ago.
I want to change xticks on a plot with matplotlib, say replacing for instance with a string. According to matplotlib manual https://matplotlib.org/3.1.0/api/_as_gen/matplotlib.pyplot.xticks.html I did the following code :
import matplotlib.pyplot as plt
import numpy as np
x=np.arange(10)
y=x**2
plt.figure()
plt.plot(x,y)
locs, labels=plt.xticks()
new_xticks=['test' for d in locs]
plt.xticks(new_xticks, rotation=45, horizontalalignment='right')
The problem is when I do this, ticks on x axis are not modified, and I get the following error
ConversionError: Failed to convert value(s) to axis units: ['test',
'test', 'test', 'test', 'test', 'test', 'test']
EDIT : I want to have the ticks at the same place of the original plot, which x axis don't go beyond min and max value, as in the following picture :
Thanks in advance for your help !
EDIT2 : its not a duplicate as I do it directly without using subplots
Do something like this:
import matplotlib.pyplot as plt
import numpy as np
x=np.arange(10)
y=x**2
plt.figure()
plt.plot(x,y)
locs, labels=plt.xticks()
x_ticks = []
new_xticks=['test' for d in locs]
plt.xticks(locs,new_xticks, rotation=45, horizontalalignment='right')
plt.show()
Output:
You are modifying the ticks. But the ticks need to be numbers. If you want to modify the tick-labels you can do so via
plt.xticks(locs, new_xticks)
This question already has answers here:
How do I change the size of figures drawn with Matplotlib?
(14 answers)
Closed 4 years ago.
As you can see the code produces a barplot that is not as clear and I want to make the figure larger so the values can be seen better. This doesn't do it. What is the correct way?
x is a dataframe and x['user'] is the x axis in the plot and x['number'] is the y.
import matplotlib.pyplot as plt
%matplotlib inline
plt.bar(x['user'], x['number'], color="blue")
plt.figure(figsize=(20,10))
The line with the plt.figure doesn't change the initial dimensions.
One option (as mentioned by #tda), and probably the best/most standard way, is to put the plt.figure before the plt.bar:
import matplotlib.pyplot as plt
plt.figure(figsize=(20,10))
plt.bar(x['user'], x['number'], color="blue")
Another option, if you want to set the figure size after creating the figure, is to use fig.set_size_inches (note I used plt.gcf here to get the current figure):
import matplotlib.pyplot as plt
plt.bar(x['user'], x['number'], color="blue")
plt.gcf().set_size_inches(20, 10)
It is possible to do this all in one line, although its not the cleanest code. First you need to create the figure, then get the current axis (fig.gca), and plot the barplot on there:
import matplotlib.pyplot as plt
plt.figure(figsize=(20, 10)).gca().bar(x['user'], x['number'], color="blue")
Finally, I will note that it is often better to use the matplotlib object-oriented approach, where you save a reference to the current Figure and Axes and call all plotting functions on them directly. It may add more lines of code, but it is usually clearer code (and you can avoid using things like gcf() and gca()). For example:
import matplotlib.pyplot as plt
fig = plt.figure(figsize=(20, 10))
ax = fig.add_subplot(111)
ax.bar(x['user'], x['number'], color="blue")
Try setting up the size of the figure before assigning what to plot, as below:
import matplotlib.pyplot as plt
%matplotlib inline
plt.figure(figsize=(20,10))
plt.bar(x['user'], x['number'], color="blue")
This question already has answers here:
How can I make the xtick labels of a plot be simple drawings using matplotlib?
(2 answers)
Closed 5 years ago.
I have a series of small, fixed width images and I want to replace the tick labels with them. For example, consider the following minimal working example:
import numpy as np
import pylab as plt
A = np.random.random(size=(5,5))
fig, ax = plt.subplots(1, 1)
ax.matshow(A)
plt.show()
I would like to replace the "0" with a custom image. I can turn off the labels, load an image into an array and display it just fine. However, I'm unsure of
Where the locations of the tick labels are, since they lie outside the plot.
Use imshow to display that image when it it will be "clipped" if put into an axis.
My thought were to use set_clip_on somehow or a custom artist, but I haven't made much progress.
Interesting question, and potentially has many possible solutions. Here is my approach, basically first calculate where the label '0' is, then draw a new axis there using absolute coordinates, and finally put the image there:
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import pylab as pl
A = np.random.random(size=(5,5))
fig, ax = plt.subplots(1, 1)
xl, yl, xh, yh=np.array(ax.get_position()).ravel()
w=xh-xl
h=yh-yl
xp=xl+w*0.1 #if replace '0' label, can also be calculated systematically using xlim()
size=0.05
img=mpimg.imread('microblog.png')
ax.matshow(A)
ax1=fig.add_axes([xp-size*0.5, yh, size, size])
ax1.axison = False
imgplot = ax1.imshow(img,transform=ax.transAxes)
plt.savefig('temp.png')