Extend matplotlib line plot across chart - python

I've created this plot, but it doesn't extend all the way across the figure for some reason. Can anyone help explain why?
Chart =
Code =
fig, ax = plt.subplots()
ax.plot(trip.index, trip.gas, marker='.',linestyle='-')
plt.xticks(np.arange(min(trip.index), max(trip.index), 7))
ax.set_xticklabels(map(str, ax.get_xticks()/7))
plt.xlabel('Week #')
plt.ylabel('Trip Cost ($)')

Matplotlib tends to include some space around the data. If you don't want that, you can adjust the axis ranges manually. This can be done via
plt.xlim(min(trip.index),max(trip.index))

Related

Using pyplot from Plots.jl. How to make several subplots have only one colobar?

I am using Plots.jl to make several plots in the same figure. When using the pyplot backend, each plot has it's own colorbar, which I don't want as they have the same data. I am trying to replicate the answer from this question, however I don't know in detail of the machinery under the Plots.jl API, so I haven't been able to replicate it. My plot is done as:
using Plots;pyplot()
p1 = plot(a,st=:contour,fill=true)
p2 = plot(b,st=:contour,fill=true)
p = plot(p1,p2)
And, the answer (which is in python) from the link is this:
fig, axes = plt.subplots(nrows=2, ncols=2)
for ax in axes.flat:
im = ax.imshow(np.random.random((10,10)), vmin=0, vmax=1)
fig.subplots_adjust(right=0.8)
cbar_ax = fig.add_axes([0.85, 0.15, 0.05, 0.7])
fig.colorbar(im, cax=cbar_ax)
plt.show()
As far as I understand, the code inside the for is actually making the plots in the axes created by plt.subplots (in my case this is done by Plots.jl
The next line makes the plots closer, and then the line fig.add_axes creates a new axis for the colorbar.
Finally, the line of fig.colorbar creates a colorbar in the new axis and uses the data from the last plot in the for loop.
My current code is:
cbar_ax = p.o[:add_axes]([0.85, 0.15, 0.05, 0.7]);
p.o[:colorbar](p.o[:axes][1][:contourf],cax=cbar_ax)
display(p)
And it doesn't work (I wouldn't expect it to work because I don't know what I'm doing.
The error I get is:
AttributeError("'function' object has no attribute 'autoscale_None'")
Which makes me think p.o:axes[:contourf] is not the way to summon what I am trying to.
Can anyone help out? Thanks
In general, if you want to use code on the PyPlot object it's better to just use PyPlot and forget about Plots. The mix rarely works in practice.
If you do want to use Plots you should be able to do
using Plots;pyplot()
lims = extrema([a;b])
p1 = plot(a,st=:contour,fill=true, colorbar = false)
p2 = plot(b,st=:contour,fill=true, colorbar = true, clims = lims)
p = plot(p1,p2)
One of the subplots will be much wider than the other - you probably need to adjust with #layout to get them the same width.

Python - save color from bar chart similar to get_color() for line charts

Is there a way to save the color of a bar plot in a variable to be used to set tick and label colors for an axis? I know this is possible using get_color() for line plots, but it does not work for bar plots.
style_format='seaborn'
mpl.style.use(style_format)
fig, ax_1 = plt.subplots()
ax_2 = ax_1.twinx()
ax_2.grid(None)
plot_1, = ax_1.errorbar(df['date'].tolist(), ptt['avg'].tolist(),
yerr=df['std'].tolist(), fmt='-o')
bar_1 = ax_2.bar(df['date'].tolist(), df['count'].tolist(), alpha=0.25)
plot_1_color = plot_1.get_color()
#this is where the code breaks. have tried get_facecolor() as well
bar_1_color = bar_1.get_color()
ax_1.yaxis.label.set_color(plot_1_color)
ax_2.yaxis.label.set_color(bar_1_color)
I have not found a way to do this in either the matplotlib documentation or anywhere else. Any help is much appreciated.
Thanks

Avoid overlapping on seaborn plots

I'm making some EDA using pandas and seaborn, this is the code I have to plot the histograms of a group of features:
skewed_data = pd.DataFrame.skew(data)
skewed_features =skewed_data.index
fig, axs = plt.subplots(ncols=len(skewed_features))
plt.ticklabel_format(style='sci', axis='both', scilimits=(0,0))
for i,skewed_feature in enumerate(skewed_features):
g = sns.distplot(data[column])
sns.distplot(data[skewed_feature], ax=axs[i])
This is the result I'm getting:
Is not readable, how can I avoid that issue?
I know you are concerning about the layout of the figures. However, you need to first decide how to represent your data. Here are two choices for your case
(1) Multiple lines in one figure and
(2) Multiple subplots 2x2, each subplot draws one line.
I am not quite familiar with searborn, but the plotting of searborn is based on matplotlib. I could give you some basic ideas.
To archive (1), you can first declare the figure and ax, then add all line to this ax. Example codes:
import matplotlib.pyplot as plt
fig, ax = plt.subplots()
# YOUR LOOP, use the ax parameter
for i in range(3)
sns.distplot(data[i], ax=ax)
To archive (2), same as above, but with different number subplots, and put your line in the different subplot.
# Four subplots, 2x2
fig, axarr = plt.subplots(2,2)
# YOUR LOOP, use different cell
You may check matplotlib subplots demo. To do a good visualization is a very tough work. There are so many documents to read. Check the gallery of matplotlib or seaborn is a good and quick way to understand how some kinds of visualization are implemented.
Thanks.

ValueError when using matplotlib tight_layout()

Ok, this is my first time asking a question on here, so please be patient with me ;-)
I'm trying to create a series of subplots (with two y-axes each) in a figure using matplotlib and then saving that figure. I'm using GridSpec to create a grid for the subplots and realised that they're overlapping a little, which I don't want. So I'm trying to use tight_layout() to sort this out, which according to the matplotlib documentation should work just fine. Simplifying things a bit, my code looks something like this:
import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
fig = plt.figure(num=None, facecolor='w', edgecolor='k')
grid = gridspec.GridSpec(2, numRows)
# numRows comes from the number of subplots required
# then I loop over all the data files I'm importing and create a subplot with two y-axes each time
ax1 = fig.add_subplot(grid[column, row])
# now I do all sorts of stuff with ax1...
ax2 = ax1.twinx()
# again doing some stuff here
After the loop for data processing is done and I have created all the subplots, I eventually end with
fig.tight_layout()
fig.savefig(str(location))
As far as I can work out, this should work, however when calling tight_layout(), I get a ValueError from the function self.subplotpars: left cannot be >= right. My question is: How do I figure out what's causing this error and how do I fix it?
I've had this error before, and I have a solution that worked for me. I'm not sure if it will work for you though. In matplotlib, the command
plt.fig.subplots_adjust()
can be used to sort of stretch the plot. The left and bottom stretch more the smaller the number gets, while the top and right stretch more the greater the number is. So if left is greater than or equal to the right, or bottom is greater than or equal to the top, than the graph would kind of flip over. I adjusted my command to look like this:
fig = plt.figure()
fig.subplots_adjust(bottom = 0)
fig.subplots_adjust(top = 1)
fig.subplots_adjust(right = 1)
fig.subplots_adjust(left = 0)
Then you can fill in your own numbers to adjust this, as long as you keep the left and bottom smaller. I hope this fixes your problem.

set_data and autoscale_view matplotlib

I have multiple lines to be drawn on the same axes, and each of them are dynamically updated (I use set_data), The issue being that i am not aware of the x and y limits of each of the lines. And axes.autoscale_view(True,True,True) / axes.set_autoscale_on(True) are not doing what they are supposed to. How do i auto scale my axes?
import matplotlib.pyplot as plt
fig = plt.figure()
axes = fig.add_subplot(111)
axes.set_autoscale_on(True)
axes.autoscale_view(True,True,True)
l1, = axes.plot([0,0.1,0.2],[1,1.1,1.2])
l2, = axes.plot([0,0.1,0.2],[-0.1,0,0.1])
#plt.show() #shows the auto scaled.
l2.set_data([0,0.1,0.2],[-1,-0.9,-0.8])
#axes.set_ylim([-2,2]) #this works, but i cannot afford to do this.
plt.draw()
plt.show() #does not show auto scaled
I have referred to these already, this , this.
In all cases I have come across, the x,y limits are known. I have multiple lines on the axes and their ranges change, keeping track of the ymax for the entire data is not practical
A little bit of exploring got me to this,
xmin,xmax,ymin,ymax = matplotlib.figure.FigureImage.get_extent(FigureImage)
But here again, i do not know how to access FigureImage from the Figure instance.
Using matplotlib 0.99.3
From the matplotlib docs for autoscale_view:
The data limits are not updated automatically when artist data are changed after the artist has been added to an Axes instance. In that case, use matplotlib.axes.Axes.relim() prior to calling autoscale_view.
So, you'll need to add two lines before your plt.draw() call after the set_data call:
axes.relim()
axes.autoscale_view(True,True,True)

Categories

Resources