ASKSAGE: Sage Q&A Forum - RSS feedhttps://ask.sagemath.org/questions/Q&A Forum for SageenCopyright Sage, 2010. Some rights reserved under creative commons license.Tue, 08 Jun 2021 01:08:17 +0200combine sage plot with matplotlibhttps://ask.sagemath.org/question/8273/combine-sage-plot-with-matplotlib/As some others I'm also searching for a convenient way for merging sage Graphics and figures from matplotlib.
Actually I don't understand why this is so difficult since Sage uses matplotlib internally. Nevertheless there seems to be no way for combining plots from both packages.
The best way would be to wrap a matplotlib plot into a Sage Graphics object.
I really love Sage's plot(...)+plot(...) syntax, but unfortunately there are some important plot types missing (e.g. errorbar plot). Of course one can do all plotting in matlotlib, but it would be more convenient to handle sage objects.
I saw in the sage documentation that one can get a matplotlib figure from a Graphics object, but didn't found a way to draw on it with matplotlib.
Does anyone know any way for combining plots from those packages?Sun, 14 Aug 2011 16:39:54 +0200https://ask.sagemath.org/question/8273/combine-sage-plot-with-matplotlib/Answer by ADuC812 for <p>As some others I'm also searching for a convenient way for merging sage Graphics and figures from matplotlib.
Actually I don't understand why this is so difficult since Sage uses matplotlib internally. Nevertheless there seems to be no way for combining plots from both packages.</p>
<p>The best way would be to wrap a matplotlib plot into a Sage Graphics object.
I really love Sage's plot(...)+plot(...) syntax, but unfortunately there are some important plot types missing (e.g. errorbar plot). Of course one can do all plotting in matlotlib, but it would be more convenient to handle sage objects.</p>
<p>I saw in the sage documentation that one can get a matplotlib figure from a Graphics object, but didn't found a way to draw on it with matplotlib.</p>
<p>Does anyone know any way for combining plots from those packages?</p>
https://ask.sagemath.org/question/8273/combine-sage-plot-with-matplotlib/?answer=13150#post-id-13150For some time, I was looking for a way how to generate several sage Graphics() objects and plot them on a matplotlib canvas in an arbitrary arrangement, using .matplotlib() function. It went out not being straightforward. I decided that the solution I've found may be interesting for others as well. The following code produces a plot with a nice inset:
#make some graphs
x=var('x')
g=plot(sin(x))
g_ins=plot(cos(x))
# plot main figure
from matplotlib.figure import Figure
figure = Figure() # you may set the size here
main_plot = figure.add_axes((0.2,0.2,0.7,0.7))
g.matplotlib('a.svg', figure=figure, sub=main_plot)
# plot an inset
inset = figure.add_axes((0.6,0.2,0.3,0.3))
g_ins.matplotlib('a.svg', figure=figure, sub=inset)
# display graph (note that only single sage Graphics object has to be saved )
g_ins.save('a.svg', figure=figure, sub=inset)
UPD: if figures are drawn strangely, add
aspect_ratio='automatic'
to matplotlib() parameters. By default it is 1.0, which may be undesired.
Also, you may want to draw the figure itself, not by Graphics().save() function. Replace the last line with the following:
from matplotlib.backends.backend_agg import FigureCanvasAgg
figure.set_canvas(FigureCanvasAgg(figure))
figure.savefig('a.svg')
Thu, 19 Jan 2012 08:04:36 +0100https://ask.sagemath.org/question/8273/combine-sage-plot-with-matplotlib/?answer=13150#post-id-13150Comment by ADuC812 for <p>For some time, I was looking for a way how to generate several sage Graphics() objects and plot them on a matplotlib canvas in an arbitrary arrangement, using .matplotlib() function. It went out not being straightforward. I decided that the solution I've found may be interesting for others as well. The following code produces a plot with a nice inset:</p>
<pre><code>#make some graphs
x=var('x')
g=plot(sin(x))
g_ins=plot(cos(x))
# plot main figure
from matplotlib.figure import Figure
figure = Figure() # you may set the size here
main_plot = figure.add_axes((0.2,0.2,0.7,0.7))
g.matplotlib('a.svg', figure=figure, sub=main_plot)
# plot an inset
inset = figure.add_axes((0.6,0.2,0.3,0.3))
g_ins.matplotlib('a.svg', figure=figure, sub=inset)
# display graph (note that only single sage Graphics object has to be saved )
g_ins.save('a.svg', figure=figure, sub=inset)
</code></pre>
<p>UPD: if figures are drawn strangely, add</p>
<pre><code>aspect_ratio='automatic'
</code></pre>
<p>to matplotlib() parameters. By default it is 1.0, which may be undesired. </p>
<p>Also, you may want to draw the figure itself, not by Graphics().save() function. Replace the last line with the following:</p>
<pre><code>from matplotlib.backends.backend_agg import FigureCanvasAgg
figure.set_canvas(FigureCanvasAgg(figure))
figure.savefig('a.svg')
</code></pre>
https://ask.sagemath.org/question/8273/combine-sage-plot-with-matplotlib/?comment=20489#post-id-20489after messing a bit with aspect ratio, added an update about it. It would be good to add it to your example as wellThu, 19 Jan 2012 11:37:33 +0100https://ask.sagemath.org/question/8273/combine-sage-plot-with-matplotlib/?comment=20489#post-id-20489Comment by kcrisman for <p>For some time, I was looking for a way how to generate several sage Graphics() objects and plot them on a matplotlib canvas in an arbitrary arrangement, using .matplotlib() function. It went out not being straightforward. I decided that the solution I've found may be interesting for others as well. The following code produces a plot with a nice inset:</p>
<pre><code>#make some graphs
x=var('x')
g=plot(sin(x))
g_ins=plot(cos(x))
# plot main figure
from matplotlib.figure import Figure
figure = Figure() # you may set the size here
main_plot = figure.add_axes((0.2,0.2,0.7,0.7))
g.matplotlib('a.svg', figure=figure, sub=main_plot)
# plot an inset
inset = figure.add_axes((0.6,0.2,0.3,0.3))
g_ins.matplotlib('a.svg', figure=figure, sub=inset)
# display graph (note that only single sage Graphics object has to be saved )
g_ins.save('a.svg', figure=figure, sub=inset)
</code></pre>
<p>UPD: if figures are drawn strangely, add</p>
<pre><code>aspect_ratio='automatic'
</code></pre>
<p>to matplotlib() parameters. By default it is 1.0, which may be undesired. </p>
<p>Also, you may want to draw the figure itself, not by Graphics().save() function. Replace the last line with the following:</p>
<pre><code>from matplotlib.backends.backend_agg import FigureCanvasAgg
figure.set_canvas(FigureCanvasAgg(figure))
figure.savefig('a.svg')
</code></pre>
https://ask.sagemath.org/question/8273/combine-sage-plot-with-matplotlib/?comment=20492#post-id-20492I've made adding an example like this `http://trac.sagemath.org/sage_trac/ticket/12326`.Thu, 19 Jan 2012 09:02:47 +0100https://ask.sagemath.org/question/8273/combine-sage-plot-with-matplotlib/?comment=20492#post-id-20492Answer by buergi for <p>As some others I'm also searching for a convenient way for merging sage Graphics and figures from matplotlib.
Actually I don't understand why this is so difficult since Sage uses matplotlib internally. Nevertheless there seems to be no way for combining plots from both packages.</p>
<p>The best way would be to wrap a matplotlib plot into a Sage Graphics object.
I really love Sage's plot(...)+plot(...) syntax, but unfortunately there are some important plot types missing (e.g. errorbar plot). Of course one can do all plotting in matlotlib, but it would be more convenient to handle sage objects.</p>
<p>I saw in the sage documentation that one can get a matplotlib figure from a Graphics object, but didn't found a way to draw on it with matplotlib.</p>
<p>Does anyone know any way for combining plots from those packages?</p>
https://ask.sagemath.org/question/8273/combine-sage-plot-with-matplotlib/?answer=12576#post-id-12576Wow hey wait a minute, I found one way to do it. But unfortunately I hoped to get it working the other way round, i.e. converting a matplotlib figure into a
import matplotlib.pyplot as pl
pl.errorbar(xs,ys,yerr=dys,fmt="ro")
plot(lambda x:f(x),(0,200)).matplotlib(figure=pl.gcf())
pl.savefig('myplot')Sun, 14 Aug 2011 16:52:08 +0200https://ask.sagemath.org/question/8273/combine-sage-plot-with-matplotlib/?answer=12576#post-id-12576Answer by kcrisman for <p>As some others I'm also searching for a convenient way for merging sage Graphics and figures from matplotlib.
Actually I don't understand why this is so difficult since Sage uses matplotlib internally. Nevertheless there seems to be no way for combining plots from both packages.</p>
<p>The best way would be to wrap a matplotlib plot into a Sage Graphics object.
I really love Sage's plot(...)+plot(...) syntax, but unfortunately there are some important plot types missing (e.g. errorbar plot). Of course one can do all plotting in matlotlib, but it would be more convenient to handle sage objects.</p>
<p>I saw in the sage documentation that one can get a matplotlib figure from a Graphics object, but didn't found a way to draw on it with matplotlib.</p>
<p>Does anyone know any way for combining plots from those packages?</p>
https://ask.sagemath.org/question/8273/combine-sage-plot-with-matplotlib/?answer=12579#post-id-12579The correct answer to this question is [Trac 5128](http://trac.sagemath.org/sage_trac/ticket/5128). Unfortunately, this has not yet been finished. But once this is done, what you want will be possible.
It's certainly possible in principle, but, as you have seen, it's quite annoying in practice. The main reason is that Sage plots are NOT really mpl plots until we actually save or show them as graphics files; until then they are Sage-y Python objects. Look at the source code *file* for some plot type, under the `_render_on_subplot` method for where mpl really is used.
Any contribution to this patch would be very welcome, by the way!Mon, 15 Aug 2011 09:47:09 +0200https://ask.sagemath.org/question/8273/combine-sage-plot-with-matplotlib/?answer=12579#post-id-12579Comment by Cheng for <p>The correct answer to this question is <a href="http://trac.sagemath.org/sage_trac/ticket/5128">Trac 5128</a>. Unfortunately, this has not yet been finished. But once this is done, what you want will be possible. </p>
<p>It's certainly possible in principle, but, as you have seen, it's quite annoying in practice. The main reason is that Sage plots are NOT really mpl plots until we actually save or show them as graphics files; until then they are Sage-y Python objects. Look at the source code <em>file</em> for some plot type, under the <code>_render_on_subplot</code> method for where mpl really is used.</p>
<p>Any contribution to this patch would be very welcome, by the way!</p>
https://ask.sagemath.org/question/8273/combine-sage-plot-with-matplotlib/?comment=57469#post-id-57469It's quite unfortunate that this trac is still not finished... Any updates?Tue, 08 Jun 2021 01:08:17 +0200https://ask.sagemath.org/question/8273/combine-sage-plot-with-matplotlib/?comment=57469#post-id-57469