I have a plot that looks like this (this is the famous Wine dataset):
As you can see, the x-axis labels overlap and thus I need to be rotated.
NB! I am not interested in rotating the x-ticks (as explained here), but the label text, i.e. alcohol, malic_acid, etc.
The logic of creating the plot is the following: I create a grid using axd = fig.subplot_mosaic(...) and then for the bottom plots I set the labels with axd[...].set_xlabel("something"). Would be great if set_xlabel would take a rotation parameter, but unfortunately that is not the case.
Based on the documentation set_xlabel accepts text arguments, of which rotation is one.
The example I used to test this is shown below, though .
import matplotlib.pyplot as plt
import numpy as np
plt.plot()
plt.gca().set_xlabel('Test', rotation='vertical')
Related
I'd like to create a scatter plot in Bokeh. Right now, I am using bokeh.plotting.figure.circle to create one. If I set the radius=radvar argument, where radvar is a valid string for my source, can I add some kind of legend so the viewer can see the scale?
Here's an example of what I'm doing now:
p=figure(tools=TOOLS)
p.circle(
x=xvar,
y=yvar,
radius=radvar,
radius_units='screen',
color={
'field':colorvar,
'transform':color_mapper},
source=data)
Seaborn has support for this kind of legend. Here's an example I found on the internet:
I'm not picky with howthe scale is shown. It could be just outlines, for example.
for legend, as far as i know, no. but for glyphs, yes. points.glyph.size (points name refers to points = p.scatter(...),) you could create size in data and create different sizes.
`
I’m trying to customise individual legend labels. In the example below, the legend contains two items. I’d like to make the text bold for only the second legend label.
Here’s a general outline of the code:
leg = plt.legend()
for text in leg.get_texts():
text.set_fontweight...
Here’s a runnable example:
import matplotlib.pyplot as plt
X=range(10)
Y=range(100,110)
Z=range(105,115)
plt.plot(X,Y,label='normal')
plt.plot(X,Z,label='bold')
fontweights=['normal','bold']
leg=plt.legend()
for fw,text in zip(fontweights,leg.get_texts()):
text.set_fontweight(fw)
plt.show()
Here's the output:
enter image description here
The plot produced shows that set_fontweight() changes both labels to bold. So is this a bug with set_fontweight(), or am I doing something wrong?
Similar functions, such as text.set_color(), can be used to modify legend labels individually.
Lastly, I’m using matplotlib version 3.2.2.
Thanks!
I have matplotlib 3.3.4 running, and get a bold and unbold legend entry - see attached image - so I think an upgrade should fix the problem.
sns.boxplot(data=df, width=0.5)
plt.title(f'Distribution of scores for initial and resubmission\
\nonly among students who resubmitted at all.\
\n(n = {df.shape[0]})')
I want to use a bigger font, and leave more space in the top white margin so that the title doesn't get crammed in. Surprisingly, I am totally unable to find the option despite some serious googling!
The basic problem you have is that the multi-line title is too tall, and is rendered "off the page".
A few options for you:
the least effort solution is probably to use tight_layout(). plt.tight_layout() manipulates the subplot locations and spacing so that labels, ticks and titles fit more nicely.
if this isn't enough, also look at plt.subplots_adjust() which gives you control over how much whitespace is used around one or more subfigures; you can modify just one aspect at at time, and all the other settings are left alone. In your case, you could use plt.subplots_adjust(top=0.8).
If you are generating a final figure for publication or similar, you might be aiming to tweak a lot to perfect it. In this case, you can precisely control the (sub)plot locations, using add_axes (see this example https://stackoverflow.com/a/17479417).
Here is an example, with a 6-line title for emphasis. The left panel shows the default - with half the title clipped off. The right panel has all measurements the same except the top; the middle has automatically removed whitespace on all sides.
import seaborn as sns
import numpy as np
import matplotlib.pyplot as plt
data = 55 + 5* np.random.randn(1000,) # some data
vlongtitle = "\n".join(["long title"]*6) # a 6-line title
# using tight_layout, all the margins are reduced
plt.figure()
sns.boxplot(data, width=0.5)
plt.title(vlongtitle)
plt.tight_layout()
# 2nd option, just edit one aspect.
plt.figure()
sns.boxplot(data, width=0.5)
plt.title(vlongtitle)
plt.subplots_adjust(top=0.72)
I have started my IPython Notebook with
ipython notebook --pylab inline
This is my code in one cell
df['korisnika'].plot()
df['osiguranika'].plot()
This is working fine, it will draw two lines, but on the same chart.
I would like to draw each line on a separate chart.
And it would be great if the charts would be next to each other, not one after the other.
I know that I can put the second line in the next cell, and then I would get two charts. But I would like the charts close to each other, because they represent the same logical unit.
You can also call the show() function after each plot.
e.g
plt.plot(a)
plt.show()
plt.plot(b)
plt.show()
Make the multiple axes first and pass them to the Pandas plot function, like:
fig, axs = plt.subplots(1,2)
df['korisnika'].plot(ax=axs[0])
df['osiguranika'].plot(ax=axs[1])
It still gives you 1 figure, but with two different plots next to each other.
Something like this:
import matplotlib.pyplot as plt
... code for plot 1 ...
plt.show()
... code for plot 2...
plt.show()
Note that this will also work if you are using the seaborn package for plotting:
import matplotlib.pyplot as plt
import seaborn as sns
sns.barplot(... code for plot 1 ...) # plot 1
plt.show()
sns.barplot(... code for plot 2 ...) # plot 2
plt.show()
Another way, for variety. Although this is somewhat less flexible than the others. Unfortunately, the graphs appear one above the other, rather than side-by-side, which you did request in your original question. But it is very concise.
df.plot(subplots=True)
If the dataframe has more than the two series, and you only want to plot those two, you'll need to replace df with df[['korisnika','osiguranika']].
I don't know if this is new functionality, but this will plot on separate figures:
df.plot(y='korisnika')
df.plot(y='osiguranika')
while this will plot on the same figure: (just like the code in the op)
df.plot(y=['korisnika','osiguranika'])
I found this question because I was using the former method and wanted them to plot on the same figure, so your question was actually my answer.
I am a new user to the python & matplotlib, this might be a simple question but I searched the internet for hours and couldn't find a solution for this.
I am plotting precipitation data from which is in the NetCDF format. What I find weird is that, the data doesn't have any negative values in it.(I checked that many times,just to make sure). But the value in the colorbar starts with a negative value (like -0.0000312 etc). It doesnt make sense because I dont do any manipulations to the data, other that just selecting a part of the data from the big file and plotting it.
So my code doesn't much to it. Here is the code:
from mpl_toolkits.basemap import Basemap
import numpy as np
import matplotlib.pyplot as plt
from netCDF4 import Dataset
cd progs
f=Dataset('V21_GPCP.1979-2009.nc')
lats=f.variables['lat'][:]
lons=f.variables['lon'][:]
prec=f.variables['PREC'][:]
la=lats[31:52]
lo=lons[18:83]
pre=prec[0,31:52,18:83]
m = Basemap(width=06.e6,height=05.e6,projection='gnom',lat_0=15.,lon_0=80.)
x, y = m(*np.meshgrid(lo,la))
m.drawcoastlines()
m.drawmapboundary(fill_color='lightblue')
m.drawparallels(np.arange(-90.,120.,5.),labels=[1,0,0,0])
m.drawmeridians(np.arange(0.,420.,5.),labels=[0,0,0,1])
cs=m.contourf(x,y,pre,50,cmap=plt.cm.jet)
plt.colorbar()
The output that I got for that code was a beautiful plot, with the colorbar starting from the value -0.00001893, and the rest are positive values, and I believe are correct. Its just the minimum value thats bugging me.
I would like to know:
Is there anything wrong in my code? cos I know that the data is right.
Is there a way to manually change the value to 0?
Is it right for the values in the colorbar to change everytime we run the code, cos for the same data, the next time I run the code, the values go like this " -0.00001893, 2.00000000, 4.00000000, 6.00000000 etc"
I want to customize them to "0.0, 2.0, 4.0, 6.0 etc"
Thanks,
Vaishu
Yes, you can manually format everything about the colorbar. See this:
import matplotlib.colors as mc
import matplotlib.pyplot as plt
plt.imshow(X, norm=mc.Normalize(vmin=0))
plt.colorbar(ticks=[0,2,4,6], format='%0.2f')
Many plotting functions including imshow, contourf, and others include a norm argument that takes a Normalize object. You can set the vmin or vmax attributes of that object to adjust the corresponding values of the colorbar.
colorbar takes the ticks and format arguments to adjust which ticks to display and how to display them.