ipython-qtconsole: change size of displayed plot - numpy

I want to use ipython to display plots. I start it as:
ipython qtconsole --pylab=inline
the plots are drawn inline, and seem to have fixed size. Is there any way, once the plot is drawn, to drag the plot element with the mouse in the corner, and enlarge it? What I have in mind is similar functionality as Mathematica has

There is no way (currently) to resize the plots by simple mouse drags. I think most of us find the default figure size to be too small. This can be changed by modifying the ipython profiles.
You can resize the plot by mouse in ipython notebook.
Locate:
# Subset of matplotlib rcParams that should be different for the inline backend.
# c.InlineBackend.rc = {'font.size': 10, 'figure.figsize': (6.0, 4.0), 'figure.facecolor': (1, 1, 1, 0), 'savefig.dpi': 72, 'figure.subplot.bottom': 0.125, 'figure.edgecolor': (1, 1, 1, 0)}
Uncomment the 2nd line and change the figure size (6.4, 4.0) to desired size.
For ipython-notebook, modify the ipython_notebook_config.py file. For ipython-qtconsole, change the ipython_qtconsole_config.py file.

If you're using Spyder, you can set figures to draw in their own pop-up window, and then you can resize them freely from there. Check out this guide for details:
https://www.scivision.co/spyder-with-ipython-make-matplotlib-plots-appear-in-own-window/

Related

Matplotlib widget, secondary y axis, twinx

i use jupyterlab together with matplotlib widgets. I have ipywidgets installed.
My goal is to choose which y-axis data is displayed in the bottom of the figure.
When i use the interactive tool to see the coordinates i get only the data of the right y-axis displayed. Both would be really nice^^ My minimal code example:
import matplotlib.pyplot as plt
import numpy as np
%matplotlib widgets
x=np.linspace(0,100)
y=x**2
y2=x**3
fig,ax=plt.subplots()
ax2=ax.twinx()
ax.plot(x,y)
ax2.plot(x,y2)
plt.show()
With this example you might ask why not to plot them to the same y-axis but thats why it is a minimal example. I would like to plot data of different units.
To choose which y-axis is used, you can set the zorder property of the axes containing this y-axis to a higher value than that of the other axes (0 is the default):
ax.zorder = 1
However, that will cause this Axes to obscure the other Axes. To counteract this, use
ax.set_facecolor((0, 0, 0, 0))
to make the background color of this Axes transparent.
Alternatively, use the grab_mouse function of the figure canvas:
fig.canvas.grab_mouse(ax)
See here for the (minimal) documentation for grab_mouse.
The reason this works is this:
The coordinate line shown below the figure is obtained by an event callback which ultimately calls matplotlib.Axes.format_coord() on the axes instance returned by the inaxes property of the matplotlib events that are being generated by your mouse movement. This Axes is the one returned by FigureCanvasBase.inaxes() which uses the Axes zorder, and in case of ties, chooses the last Axes created.
However, you can tell the figure canvas that one Axes should receive all mouse events, in which case this Axes is also set as the inaxes property of generated events (see the code).
I have not found a clean way to make the display show data from both Axes. The only solution I have found would be to monkey-patch NavigationToolbar2._mouse_event_to_message (also here) to do what you want.

Extra entries ignored in axis legend

I’m trying to reproduce some plots from this video with up-to-date data and superimposing points on the lines for measures taken by governments. Using pandas for the data, and to call the plot commands.
wI have no trouble plotting the lines and appropriate legends. I then add superimposed points, for which I defined these properties:
point_opts = lambda marker, color: {'label': '', 'color': 'w', 'marker': marker, 'markeredgecolor': color, 'markeredgewidth': 3, 'linestyle': None}
I would like to only add those to the legend once, instead of once per country, hence the empty label.
I then try to modify the legend as follows:
handles, labels = ax.get_legend_handles_labels()
for props in ({**point_opts(marker, 'black'), 'label': measure} for measure, marker in points.items()):
handles.append(matplotlib.lines.Line2D([], [], **props))
labels.append(props['label'])
ax.legend(handles=handles, labels=labels)
However this does not change the axis legends (and no error messages are shown). The values seem right however. For example, if I add a second plot, on the Figure:
fig.legend(handles=handles, labels=labels, loc='center left')
I then get the result below.
Why is this happening? How can I actually modify my plot axis? Using python 3.7.3 and matplotlib 3.1.3 on OpenSuse x64, if that’s of any relevance.
Ugh alright, I’ve found it… I was, somewhere later, moving the legend around with:
ax.legend(loc='center left', bbox_to_anchor=(1, 0.5))
Apparently that resets the legend content to whatever the plot commands put there, erasing andy manual additions.

How can I draw axes with a 45 degree rotation?

I have a set of 7x4 plots arranged in a grid using subplot. I now want to add diagonal axes on top of these.
I know you can superpose axes on top of previously made subplots by setting the background to 'none':
ax = fig.add_subplot(111)
ax.set_axis_bgcolor('none')
But I can't find a rotated axis thing. Currently I'm trying to use a top view 3D axes, but I'm far from a usable solution there.
I'm willing to accept drawing the axis+ticks by hand, if this is the only way possible.
EDIT: using the floating_axis module, I was able to draw rotated (and sheared) axes, but unable to edit the ticks, which is very necessary for what I need. The following snippet demonstrates adding a floating_axis to an existing figure fig. Any manipulation of the axes' ticks fails.
from matplotlib.transforms import Affine2D
import mpl_toolkits.axisartist.floating_axes as floating_axes
trafo = Affine2D().skew_deg(-10,-10).rotate_deg(45)
grid_helper = floating_axes.GridHelperCurveLinear(trafo, extremes=(0, 4, 0, 4))
artistax = floating_axes.FloatingSubplot(fig, 111, grid_helper=grid_helper)
artistax.set_axis_bgcolor('none')
artistax.axis["top"].set_visible(False)
artistax.axis["right"].set_visible(False)
fig.add_subplot(artistax)

Change default background color for matplotlib plots

I am using ipython with matplotlib. Is it possible to configure the default background color for matplotlib plots? The curent (white) colour must come from somewhere. Is it possible to override it to, lets say, #CCCCCC?
Note: By default, I don't mean default for a given ipython notebook. I mean default for my matplotlib installation.
The solution suggested by #Ffisegydd works. however, after setting axes.facecolor : F4EAEA, I still get white edges around the plot:
How can I get rid of those?
UPDATE:
now I have following set in my /etc/matplotlibrc and I have restarted ipython notebook after each change;
axes.facecolor : F4EAEA
figure.facecolor : F4EAEA
figure.edgecolor : F4EAEA
savefig.facecolor : F4EAEA
savefig.edgecolor : F4EAEA
The plot looks the same as on the original screenshot. i.e. there is the white stripe around the plot.
UPDATE2:
I am using ipython, and I have following custom css in my ~/.config/ipython/profile_nbserver/static/custom/custom.css
div.output_area {
border-radius: 4px;
background: #F4EAEA !important;
border: thin solid #4a4a4a;
}
You need to set both the axes and figure background colors:
f = plt.figure(facecolor=".6")
ax = f.add_subplot(111, axisbg=".6")
ax.plot([0, 1, 2], [1, 0, 2])
There is additionally a distinction between the facecolor for the interactive plot and what gets saved; you also have to pass facecolor to f.savefig if you want a uniform background on the resulting file.
You can change the defaults with the following fields in the rcParams dictionary:
import matplotlib as mpl
mpl.rcParams["figure.facecolor"]
mpl.rcParams["axes.facecolor"]
mpl.rcParams["savefig.facecolor"]
Note that this works a little unexpectedly in the IPython notebook with an inline backend, where the "saved" version of the figure you see below the cell is not controlled by the figure parameter, but by the savefig paramter.
You can customise matplotlib in a variety of ways.
If you're looking to customise across your entire computer then matplotlib uses the "matplotlibrc" configuration file as a default.
If you wish to edit this to change the default axes facecolor (the technical term for the background) then you'll need to uncomment and adjust this line:
#axes.facecolor : white # axes background color
If you wish to set your background colour to #CCCCCC then you should change the line to:
axes.facecolor : CCCCCC # axes background color
N.B. if you re-install matplotlib this will be overwritten. To prevent this you can save it in "HOME/.matplotlib/matplotlibrc" as the example comments state.
Should you wish to change it to a different colour temporarily then simply add the following at the top of your script:
import matplotlib as mpl
mpl.rcParams['axes.facecolor'] = '111111' # Or any suitable colour...
If you should wish to modify an individual matplotlib.axes object then just use ax.set_axis_bgcolor('...').

Matplotlib - transform bbox

I printed some text into a plot. Now I want to make a copy of this text and move it to different coordinates. I guess I'll have to do this with tranform, but did not find a solution yet.
here is the code:
props = dict( facecolor='#DDDDDD', alpha=1,edgecolor='#FFFFFF',boxstyle="Square,pad=0.5")
text2=plt.text(4, 4, "text",va='top', ha='left',bbox=props)
plt.draw()
bb2=text2.get_bbox_patch().get_window_extent().transformed(ax.transData.inverted()).get_points()
To move the text to different coordinates you only need:
text2.set_position((new_x,new_y))
you could also use:
text2.set_x(new_x)
text2.set_y(new_y)