This question already has an answer here:
Half violin plot in matplotlib
(1 answer)
Closed 2 years ago.
I would like to obtain a graph similar to the one I drew:
In the x axis the date of the collected data, and in the y axis the associated densities.
I wrote these few lines:
import matplotlib.pyplot as plt
import numpy as np
import seaborn as sns
import pandas as pd
from datetime import datetime
df = pd.DataFrame(np.random.rand(7, 100), columns=['y']*100)
df.index = pd.date_range(datetime.today(), periods=7).tolist()
sns.kdeplot(data=df, y='y', fill=True, alpha=.5, linewidth=0)
plt.show()
but of course it doesn't work. How can I modify the code to get what I imagined?
Can be done easily using statsmodels.graphics.boxplots.violinplot
from statsmodels.graphics.boxplots import violinplot
fig, ax = plt.subplots()
violinplot(data=df.values, ax=ax, labels=df.index.strftime('%Y-%m-%d'), side='right', show_boxplot=False)
fig.autofmt_xdate()
Related
I have seaborn heatmap and I would like to plot a lineplot on top of it while using the same x and y axis that the heatmap is using.
I expected the line to behave like in this post and take up most of the space of the heatmap, but instead the output I got was the following plot where it only occupied a small section of the heatmap. How can I make the line take up most of the space in the heatmap?
Below is the minimal working example that produced the plot I linked above.
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import pandas as pd
num = 11
a = np.eye(num)
x = np.round(np.linspace(0, 1, num=num), 1)
y = np.round(np.linspace(0, 1, num=num), 1)
df = pd.DataFrame(a, columns=x, index=y)
f, ax = plt.subplots()
ax = sns.heatmap(df, cbar=False)
ax.axes.invert_yaxis()
sns.lineplot(x=x, y=y)
plt.show()
Perhaps just a simple fix here:
sns.lineplot(x=x*num, y=y*num)
This question already has an answer here:
adjusting subplot with a colorbar
(1 answer)
Closed 3 years ago.
I am trying to use Matplotlib to plot a time series along with its spectrogram and its associated colorbar.
Below is a MCVE:
import numpy as np
import matplotlib.pyplot as plt
import scipy.signal as scignal
import random
array=np.random.random(10000)
t,f,Sxx=scignal.spectrogram(array,fs=100)
plt.subplot(211)
plt.plot(array)
plt.subplot(212)
plt.pcolormesh(Sxx)
plt.colorbar()
This code yields the following figure:
However, I would like both subplots to have the same size:
I thought of changing the orientation of the colorbar using plt.colorbar(orientation='horizontal') but I am not satisfied with the result as the subplots end up not having the same height.
Any help will be appreciated!
The reason this happens is that plt.colorbar creates a new Axes object, which "steals" space from the lower Axes (this is the reason making a horizontal colourbar also affects the two original plots).
There are a few ways to work around this; one is to create a Figure with four Axes, allocate most of the space to the left ones, and just make one invisible:
import numpy as np
import matplotlib.pyplot as plt
import scipy.signal as scignal
import random
array = np.random.random(10000)
t, f, Sxx = scignal.spectrogram(array,fs=100)
fig, axes = plt.subplots(nrows=2, ncols=2, figsize=(5, 6), gridspec_kw={'width_ratios': [19, 1]})
(ax1, blank), (ax2, ax_cb) = axes
blank.set_visible(False)
ax1.plot(array)
m = ax2.pcolormesh(Sxx)
fig.colorbar(m, cax=ax_cb)
This question already has an answer here:
seaborn is not plotting within defined subplots
(1 answer)
Closed 1 year ago.
The seaborn documentation makes a distinction between figure-level and axes-level functions: https://seaborn.pydata.org/introduction.html#figure-level-and-axes-level-functions
I understand that functions like sns.boxplot can take an axis as argument, and can therefore be used within subplots.
But how about sns.relplot() ? Is there no way to put that into subplots?
More generally, is there any way to get seaborn to generate line plots within subplots?
For example, this doesn't work:
fig,ax=plt.subplots(2)
sns.relplot(x,y, ax=ax[0])
because relplot doesn't take axes as an argument.
Well that's not true. You can indeed pass axis objects to relplot. Below is a minimal answer. The key point here is to close the empty axis objects returned by relplot. You can then also use ax[0] or ax[1] to add additional curves to your individual subfigures just like you would do with matplotlib.
import seaborn as sns
import matplotlib.pyplot as plt
fig, ax = plt.subplots(2)
xdata = np.arange(50)
sns.set(style="ticks")
tips = sns.load_dataset("tips")
g1 = sns.relplot(x="total_bill", y="tip", hue="day", data=tips, ax=ax[0])
g2 = sns.relplot(x="total_bill", y="tip", hue="day", data=tips, ax=ax[1])
# Now you can add any curves to individual axis objects
ax[0].plot(xdata, xdata/5)
# You will have to close the additional empty figures returned by replot
plt.close(g1.fig)
plt.close(g2.fig)
plt.tight_layout()
You can also make line plot solely using seaborn as
import seaborn as sns
import numpy as np
x = np.linspace(0, 5, 100)
y = x**2
ax = sns.lineplot(x, y)
ax.set_xlabel('x-label')
ax.set_ylabel('y-label')
This question already has answers here:
How can I change the x axis in matplotlib so there is no white space?
(2 answers)
Closed 5 years ago.
I am trying to generate a histogram from a DataFrame with seaborn enabled via the DataFrame.hist method, but I keep finding extra space added to either side of the histogram itself, as seen by the red arrows in the below picture:
How can I remove these spaces? Code to reproduce this graph is as follows:
import seaborn as sns
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from random import seed, choice
seed(0)
df = pd.DataFrame([choice(range(250)) for _ in range(100)], columns=['Values'])
bins = np.arange(0, 260, 10)
df['Values'].hist(bins=bins)
plt.tight_layout()
plt.show()
plt.tight_layout() only has an effect for the "outer margins" of your plot (tick marks, ax labels etc.).
By default matplotlib's hist leaves an inner margin around the hist bar-plot. To disable you can do this:
ax = df['Values'].hist(bins=bins)
ax.margins(x=0)
plt.show()
I am trying to plot a curve in between two others filled and as soon as I have these two "plots", my x-axis become strange.
Here is my MWE:
import matplotlib.pyplot as plt
from matplotlib import dates as mdates
import datetime
import numpy as np
dates=[u'0600', u'0630', u'0700', u'0730', u'0800', u'0830', u'0900', u'0930', u'1000', u'1030']#["0800","0830","0900"]
x=[datetime.datetime.strptime(h,'%H%M') for h in dates]
y=np.arange(len(x))
tmin=y/2.
tmax=y*2.
fig, ax = plt.subplots()
ax.plot(x,y,'r')
ax.fill_between(x,tmin,tmax)
hfmt = mdates.DateFormatter('%H:%M')
ax.xaxis.set_major_formatter(hfmt)
fig.autofmt_xdate()
plt.savefig('plot.png')
plt.show()
where the x-axis should looks like
which can easily be obtained by commenting one of the plot or fill_between command line.
Any idea of how to have the second x-axis in the first figure ?
The easiest way would probably be to use
ax.x_axis.set_major_locator(mdates.MinuteLocator(byminute=[0,30]))