How to widen the amount of my X axis data displayed? - matplotlib

My X label data is definietly too long to display every single position and still have transparent look of the chart.
fig, ax = plt.subplots()
ax.bar(timestamp, attribute_history)
fig.autofmt_xdate()
plt.show()
How to display for example every each 5 positions? My X label is taken directly from json and I'd like to avoid any operations on the data.
Also, is it possible to draw a straight line up through whole chart from each division line on the X axis?

Related

Connect lines in plot

I have a plot with the numbers 1-9 on the y axis. I have a data frame (gaze data) with numbers in this range over time. ex: 333337777772221115556668888
plt.figure()
plt.plot(gazedata['time'],gazedata['roi'], linestyle='solid',color='blue')
plt.show()
Whenever the number occurs a line is plotted. I would like to connect the lines. How can I do this? In the picture I added what I need in red.

Is it possible to break x and y axis at the same time on lineplot?

I am working on drawing lineplots with matplotlib.
I checked several posts and could understand how the line break works on matplotlib (Break // in x axis of matplotlib)
However, I was wondering is it possible to break x and y axis all together at the same time.
My current drawing looks like below.
As shown on the graph, x-axis [2000,5000] waste spaces a lot.
Because I have more data that need to be drawn after 7000, I want to save more space.
Is it possible to split x-axis together with y-axis?
Or is there another convenient way to not to show specific region on lineplot?
If there is another library enabling this, I am willing to drop matplotlib and adopt others...
Maybe splitting the axis isn't your best choice. I would perhaps try inserting another smaller figure into the open space of your large figure using add_axes(). Here is a small example.
t = np.linspace(0, 5000, 1000) # create 1000 time stamps
data = 5*t*np.exp(-t/100) # and some fake data
fig, ax = plt.subplots()
ax.plot(t, data)
box = ax.get_position()
width = box.width*0.6
height = box.height*0.6
x = 0.35
y = 0.35
subax = fig.add_axes([x,y,width,height])
subax.plot(t, data)
subax.axis([0, np.max(t)/10, 0, np.max(data)*1.1])
plt.show()

Adding text using matplotlib

I am trying to build a graph using matplotlib, and I am having trouble placing descriptive text on the graph itself.
My y values range from .9 to 1.65, and x ranges from the dates 2001 to 2021 and are sourced from a datetime series.
Here are the basics of what I am working with:
fig, ax = plt.subplots(figsize=(10,7))
I know that I have to use ax.text() to place any text, but whenever I try to enter basically any values for the x and y coordinates of the text, the entire graph disappears when I re-run the cell. I have plotted the following line, but if I use the same coordinates in ax.text(), I get the output I just described. Why might this be happening?
plt.axhline(y=1.19, xmin=.032, xmax=.96)
By default, the y argument in the axhline method is in data coordinates, while the xmin and xmax arguments are in axis coordinates, with 0 corresponding to the far left of the plot, and 1 corresponding to the far right of the plot. See the axhline documentation for more information.
On the other hand, both the x and y arguments used in the text method are in data coordinates, so you position text relative to the data. However, you can change this to axis coordinates using the transform parameter. By setting this to ax.transAxes, you actually indicate that the x and y arguments should be interpreted as axis coordinates, again with 0 being the far left (or bottom) of the plot, and 1 being the far right (or top) of the plot. In this case, you would use ax.text as follows:
ax.text(x, y, 'text', transform=ax.transAxes)
Again, see the text documentation for more information.
However, it sounds like you might want to combine data and axis coordinates to place your text, because you want to reuse the arguments from axhline for your text. In this case, you need to create a transform object that interprets the x coordinate as axis coordinate, and the y coordinate as data coordinate. This is also possible by creating a blended transformation. For example:
import matplotlib.transforms as transforms
# create your ax object here
trans = transforms.blended_transform_factory(x_transform=ax.transAxes, y_transform=ax.transData)
ax.text(x, y, 'text', transform=trans)
See the Blended transformations section of the transformations tutorial for more information.
In short, you can refer to the following figure to compare the results of these various transformations:
import matplotlib.pyplot as plt
import matplotlib.transforms as transforms
fig, ax = plt.subplots()
ax.set_xlim(0, 2)
ax.set_ylim(0, 2)
# note that the line is plotted at y=1.5, but between x=1.6 and x=1.8
# because xmin/xmax are in axis coordinates
ax.axhline(1.5, xmin=.8, xmax=.9)
# x and y are in data coordinates
ax.text(0.5, 0.5, 'A')
# here, x and y are in axis coordinates
ax.text(0.5, 0.5, 'B', transform=ax.transAxes)
trans = transforms.blended_transform_factory(x_transform=ax.transAxes, y_transform=ax.transData)
# here, x is in axis coordinates, but y is in data coordinates
ax.text(0.5, 0.5, 'C', transform=trans)

Scatter plot without x-axis

I am trying to visualize some data and have built a scatter plot with this code -
sns.regplot(y="Calls", x="clientid", data=Drop)
This is the output -
I don't want it to consider the x-axis. I just want to see how the data lie w.r.t y-axis. Is there a way to do that?
As #iayork suggested, you can see the distribution of your points with a striplot or a swarmplot (you could also combine them with a violinplot). If you need to move the points closer to the y-axis, you can simply adjust the size of the figure so that the width is small compared to the height (here i'm doing 2 subplots on a 4x5 in figure, which means that each plot is roughly 2x5 in).
fig, (ax1,ax2) = plt.subplots(1,2, figsize=(4,5))
sns.stripplot(d, orient='vert', ax=ax1)
sns.swarmplot(d, orient='vert', ax=ax2)
plt.tight_layout()
However, I'm going to suggest that maybe you want to use distplot instead. This function is specifically created to show the distribution of you data. Here i'm plotting the KDE of the data, as well as the "rugplot", which shows the position of the points along the y-axis:
fig = plt.figure()
sns.distplot(d, kde=True, vertical=True, rug=True, hist=False, kde_kws=dict(shade=True), rug_kws=dict(lw=2, color='orange'))

Reducing the distance between two boxplots

I'm drawing the bloxplot shown below using python and matplotlib. Is there any way I can reduce the distance between the two boxplots on the X axis?
This is the code that I'm using to get the figure above:
import matplotlib.pyplot as plt
from matplotlib import rcParams
rcParams['ytick.direction'] = 'out'
rcParams['xtick.direction'] = 'out'
fig = plt.figure()
xlabels = ["CG", "EG"]
ax = fig.add_subplot(111)
ax.boxplot([values_cg, values_eg])
ax.set_xticks(np.arange(len(xlabels))+1)
ax.set_xticklabels(xlabels, rotation=45, ha='right')
fig.subplots_adjust(bottom=0.3)
ylabels = yticks = np.linspace(0, 20, 5)
ax.set_yticks(yticks)
ax.set_yticklabels(ylabels)
ax.tick_params(axis='x', pad=10)
ax.tick_params(axis='y', pad=10)
plt.savefig(os.path.join(output_dir, "output.pdf"))
And this is an example closer to what I'd like to get visually (although I wouldn't mind if the boxplots were even a bit closer to each other):
You can either change the aspect ratio of plot or use the widths kwarg (doc) as such:
ax.boxplot([values_cg, values_eg], widths=1)
to make the boxes wider.
Try changing the aspect ratio using
ax.set_aspect(1.5) # or some other float
The larger then number, the narrower (and taller) the plot should be:
a circle will be stretched such that the height is num times the width. aspect=1 is the same as aspect=’equal’.
http://matplotlib.org/api/axes_api.html#matplotlib.axes.Axes.set_aspect
When your code writes:
ax.set_xticks(np.arange(len(xlabels))+1)
You're putting the first box plot on 0 and the second one on 1 (event though you change the tick labels afterwards), just like in the second, "wanted" example you gave they are set on 1,2,3.
So i think an alternative solution would be to play with the xticks position and the xlim of the plot.
for example using
ax.set_xlim(-1.5,2.5)
would place them closer.
positions : array-like, optional
Sets the positions of the boxes. The ticks and limits are automatically set to match the positions. Defaults to range(1, N+1) where N is the number of boxes to be drawn.
https://matplotlib.org/3.1.1/api/_as_gen/matplotlib.pyplot.boxplot.html
This should do the job!
As #Stevie mentioned, you can use the positions kwarg (doc) to manually set the x-coordinates of the boxes:
ax.boxplot([values_cg, values_eg], positions=[1, 1.3])