SourceForge logo
SourceForge logo
Menu

matplotlib-devel

From: Darren D. <dar...@co...> - 2008年03月07日 21:58:01
I am having some trouble with the Cursor widget with the qt4agg backend. Here 
is a short script which works with the gtkagg backend with useblit either 
true or false:
----------
from matplotlib import rcParams
rcParams['backend']='gtkagg'
from pylab import *
from matplotlib.widgets import Cursor
t = arange(0.0, 1.0, 0.01)
s = sin(2*2*pi*t)
ax = subplot(111)
cursor = Cursor(ax, useblit=True)
ax.plot(t, s, 'o')
axis([0,1,-1,1])
show()
------------
If I use the qt4agg backend, with useblit False, the cursor lines do not 
render. If useblit is True, the lines render but the pixmap inside the axes 
is sheared. I've been looking at the backend_qt4agg code, the widgets.Cursor 
code, and the working animation_blit_qt4 example, but I'm stuck. Does anyone 
have any ideas?
Thanks,
Darren
From: Darren D. <dar...@co...> - 2008年03月08日 16:38:07
On Friday 07 March 2008 4:58:03 pm Darren Dale wrote:
> I am having some trouble with the Cursor widget with the qt4agg backend.
> Here is a short script which works with the gtkagg backend with useblit
> either true or false:
>
> ----------
> from matplotlib import rcParams
> rcParams['backend']='gtkagg'
> from pylab import *
> from matplotlib.widgets import Cursor
>
> t = arange(0.0, 1.0, 0.01)
> s = sin(2*2*pi*t)
> ax = subplot(111)
>
> cursor = Cursor(ax, useblit=True)
>
> ax.plot(t, s, 'o')
> axis([0,1,-1,1])
> show()
> ------------
>
> If I use the qt4agg backend, with useblit False, the cursor lines do not
> render. If useblit is True, the lines render but the pixmap inside the axes
> is sheared. I've been looking at the backend_qt4agg code, the
> widgets.Cursor code, and the working animation_blit_qt4 example, but I'm
> stuck. Does anyone have any ideas?
Here is an additional wrinkle, sometimes the pixmap is sheared, and sometimes 
it is not. The behavior seems to shift back and forth when I change the 
horizontal size of the figure window, bu I don't see a pattern emerging that 
would explain why: 556-559 pixels wide is sheared, 560-564 looks ok, 565-567 
is sheared, 568 is normal, 569 and 570 are sheared, etc. The 
animation_blit_qt4 demo also has the same problem, depending on the 
horizontal size. So confusing.
From: Darren D. <dar...@co...> - 2008年03月08日 18:07:09
On Saturday 08 March 2008 11:36:45 am Darren Dale wrote:
> On Friday 07 March 2008 4:58:03 pm Darren Dale wrote:
> > I am having some trouble with the Cursor widget with the qt4agg backend.
> > Here is a short script which works with the gtkagg backend with useblit
> > either true or false:
> >
> > ----------
> > from matplotlib import rcParams
> > rcParams['backend']='gtkagg'
> > from pylab import *
> > from matplotlib.widgets import Cursor
> >
> > t = arange(0.0, 1.0, 0.01)
> > s = sin(2*2*pi*t)
> > ax = subplot(111)
> >
> > cursor = Cursor(ax, useblit=True)
> >
> > ax.plot(t, s, 'o')
> > axis([0,1,-1,1])
> > show()
> > ------------
> >
> > If I use the qt4agg backend, with useblit False, the cursor lines do not
> > render. If useblit is True, the lines render but the pixmap inside the
> > axes is sheared. I've been looking at the backend_qt4agg code, the
> > widgets.Cursor code, and the working animation_blit_qt4 example, but I'm
> > stuck. Does anyone have any ideas?
>
> Here is an additional wrinkle, sometimes the pixmap is sheared, and
> sometimes it is not. The behavior seems to shift back and forth when I
> change the horizontal size of the figure window, bu I don't see a pattern
> emerging that would explain why: 556-559 pixels wide is sheared, 560-564
> looks ok, 565-567 is sheared, 568 is normal, 569 and 570 are sheared, etc.
> The
> animation_blit_qt4 demo also has the same problem, depending on the
> horizontal size. So confusing.
I think this problem is due to a loss of precision in _backend_agg's 
copy_from_bbox. That method takes a bbox with double precision as input, and 
constructs a rect with ints as input:
 agg::rect_i rect((int)l, height - (int)t, (int)r, height - (int)b);
A rendering buffer is created with a width based on that rect. Half of the 
time, the width of that buffer disagrees with the width reported by the 
original bbox. For example, I can kludge the bbox width so it agrees with the 
output of copy_from_bbox:
 l, b, w, h = bbox.bounds
 r = int(l+w)
 w_mod = r-int(l)
I can use w_mod instead of w as a workaround for the blitting issue I 
reported, but I wonder if there might be a better solution?
Thanks,
Darren
From: Ted D. <ted...@jp...> - 2008年03月10日 04:21:29
Attachments: error.py
I've got an MPL widget embedded in a qt application. The user interacts w/
the GUI and causes data to be shown or hidden in the plot. Since the data
can be very large (5-10 lines w/ 40,000 points in each), I've written code
that reads the data and builds Line2D objects. Then I call axes.add_line()
and line.remove() to add and remove them from my plot.
This works fine when the x axis is a floating point axis. If I switch the x
axis to dates, then when I try to re-add some removed lines, I get the error
at the bottom of the email. A script that duplicates this is attached
(though I think you need to have an interactive mode session running to
really see what happens. 
As an example:
1) read data and build 4 Line2D objects
2) user shows lines 1 and 2 
3) user hides lines 1 and 2, shows lines 3 and 4
4) user hides lines 3 and 4, shows lines 1 and 2
These steps work fine w/ floats. But if I tell the xaxis to be date
(axis.xaxis_date()), then step 4 above will give the error:
 File "./error.py", line 62, in <module>
 run( True )
 File "./error.py", line 53, in run
 ax.autoscale_view()
 File
"/group/monte/development/rh8/tools.2007_03_13/lib/python2.5/site-packages/m
atplotlib/axes.py", line 1268, in autoscale_view
 XL = self.xaxis.get_major_locator().autoscale()
 File
"/group/monte/development/rh8/tools.2007_03_13/lib/python2.5/site-packages/m
atplotlib/dates.py", line 568, in autoscale
 dmin, dmax = self.datalim_to_dt()
 File
"/group/monte/development/rh8/tools.2007_03_13/lib/python2.5/site-packages/m
atplotlib/dates.py", line 434, in datalim_to_dt
 return num2date(dmin, self.tz), num2date(dmax, self.tz)
 File
"/group/monte/development/rh8/tools.2007_03_13/lib/python2.5/site-packages/m
atplotlib/dates.py", line 234, in num2date
 if not cbook.iterable(x): return _from_ordinalf(x, tz)
 File
"/group/monte/development/rh8/tools.2007_03_13/lib/python2.5/site-packages/m
atplotlib/dates.py", line 157, in _from_ordinalf
 dt = datetime.datetime.fromordinal(ix)
ValueError: ordinal must be >= 1
Any help would be greatly appreciated. It almost seems like using date mode
is somehow changing the Line2D object. I tried not clearing the figure and
just removing the lines, but that causes other problems (the plot won't
autoscale in step 4 and I also need to toggle other items on and off -
legends and things).
Thanks,
Ted
From: Ted D. <ted...@jp...> - 2008年03月21日 21:24:35
I've been investigating performance problems we've been having w/ the Qt
backends. One problems is that zooming takes forever. I've put a lot of
timing loops into the backends to see where things are happening and found a
couple of interesting items. 
The first is that agg seems to get much slower as you zoom in. The agg draw
time goes up as the zoom level goes up. These are plots that are completely
done w/ the Ellipse patch. Using the Arc patch helps but is about 10%
slower when not zooming. 
The second (and reason for the email), is that the QtAgg backends are
redrawing the whole plot twice when zooming w/ the mouse. The problem is
the files:
backend_qt.py
backend_qt4.py
The method mouseReleaseEvent calls draw() at the end of it. This seems to
be redundant. None of the other backends call draw at the end of their
mouse release code. The release_zoom method in the toolbar already does a
draw() call which handles the zoom. In addition, this mouseReleaseEvent
code triggers a draw whenever you click anywhere in the figure.
Does anyone have any idea why the qt backends should have a draw in the
mouse release when the others don't?
Ted
From: Michael D. <md...@st...> - 2008年03月10日 12:24:39
Sorry, I didn't see this latest e-mail before I replied before. I see 
the shearing now that I've adjusted window size. Maybe it could be 
related to the fact that width != span? Anyway, I'll investigated 
further and get back.
Cheers,
Mike
Darren Dale wrote:
> On Friday 07 March 2008 4:58:03 pm Darren Dale wrote:
> 
>> I am having some trouble with the Cursor widget with the qt4agg backend.
>> Here is a short script which works with the gtkagg backend with useblit
>> either true or false:
>>
>> ----------
>> from matplotlib import rcParams
>> rcParams['backend']='gtkagg'
>> from pylab import *
>> from matplotlib.widgets import Cursor
>>
>> t = arange(0.0, 1.0, 0.01)
>> s = sin(2*2*pi*t)
>> ax = subplot(111)
>>
>> cursor = Cursor(ax, useblit=True)
>>
>> ax.plot(t, s, 'o')
>> axis([0,1,-1,1])
>> show()
>> ------------
>>
>> If I use the qt4agg backend, with useblit False, the cursor lines do not
>> render. If useblit is True, the lines render but the pixmap inside the axes
>> is sheared. I've been looking at the backend_qt4agg code, the
>> widgets.Cursor code, and the working animation_blit_qt4 example, but I'm
>> stuck. Does anyone have any ideas?
>> 
>
> Here is an additional wrinkle, sometimes the pixmap is sheared, and sometimes 
> it is not. The behavior seems to shift back and forth when I change the 
> horizontal size of the figure window, bu I don't see a pattern emerging that 
> would explain why: 556-559 pixels wide is sheared, 560-564 looks ok, 565-567 
> is sheared, 568 is normal, 569 and 570 are sheared, etc. The 
> animation_blit_qt4 demo also has the same problem, depending on the 
> horizontal size. So confusing.
>
> -------------------------------------------------------------------------
> This SF.net email is sponsored by: Microsoft
> Defy all challenges. Microsoft(R) Visual Studio 2008.
> http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
> _______________________________________________
> Matplotlib-devel mailing list
> Mat...@li...
> https://lists.sourceforge.net/lists/listinfo/matplotlib-devel
> 
-- 
Michael Droettboom
Science Software Branch
Operations and Engineering Division
Space Telescope Science Institute
Operated by AURA for NASA
From: Michael D. <md...@st...> - 2008年03月10日 12:22:52
With the qt4agg backend, I also get no cursor with "useblit=False", but 
when "useblit=True" it seems to work just fine -- I don't see any 
shearing. By shearing I assume you mean the image is warped like a 
parallelogram? Or do mean tearing, in that it isn't updating fast 
enough? (FWIW, I don't see either).
What versions of Qt do you have? I've got:
 Qt: Qt: 3.3.3, PyQt: 3.17.2
 Qt4: Qt: 4.3.0, PyQt4: 4.2
Cheers,
Mike
Darren Dale wrote:
> I am having some trouble with the Cursor widget with the qt4agg backend. Here 
> is a short script which works with the gtkagg backend with useblit either 
> true or false:
>
> ----------
> from matplotlib import rcParams
> rcParams['backend']='gtkagg'
> from pylab import *
> from matplotlib.widgets import Cursor
>
> t = arange(0.0, 1.0, 0.01)
> s = sin(2*2*pi*t)
> ax = subplot(111)
>
> cursor = Cursor(ax, useblit=True)
>
> ax.plot(t, s, 'o')
> axis([0,1,-1,1])
> show()
> ------------
>
> If I use the qt4agg backend, with useblit False, the cursor lines do not 
> render. If useblit is True, the lines render but the pixmap inside the axes 
> is sheared. I've been looking at the backend_qt4agg code, the widgets.Cursor 
> code, and the working animation_blit_qt4 example, but I'm stuck. Does anyone 
> have any ideas?
>
> Thanks,
> Darren
>
> -------------------------------------------------------------------------
> This SF.net email is sponsored by: Microsoft
> Defy all challenges. Microsoft(R) Visual Studio 2008.
> http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
> _______________________________________________
> Matplotlib-devel mailing list
> Mat...@li...
> https://lists.sourceforge.net/lists/listinfo/matplotlib-devel
> 
-- 
Michael Droettboom
Science Software Branch
Operations and Engineering Division
Space Telescope Science Institute
Operated by AURA for NASA
From: Michael D. <md...@st...> - 2008年03月10日 12:47:08
No, I didn't see this message, but I think we arrived at the same 
conclusion. I think the solution is just to calculate the width and 
height in the same way in both places (copy_to_bbox and the Qt blitting 
code in Python). We can't change bbox.bounds, since many other parts of 
the code rely on that calculation being in pure floating point. But 
there's only two places (in Qt and Qt4) that rely on the rounding 
behavior of copy_to_bbox, and IMHO, the way it does the rounding is the 
sanest way given that the edges must be integer-aligned.
I've committed these changes in r4995.
Cheers,
Mike
Darren Dale wrote:
> Hi Mike,
>
> On Monday 10 March 2008 08:24:27 am you wrote:
> 
>> Sorry, I didn't see this latest e-mail before I replied before. I see
>> the shearing now that I've adjusted window size. Maybe it could be
>> related to the fact that width != span? Anyway, I'll investigated
>> further and get back.
>> 
>
> Thanks for having a look. But before you dig to deep, did you see my last post 
> to this thread?:
>
> -----
> I think this problem is due to a loss of precision in _backend_agg's 
> copy_from_bbox. That method takes a bbox with double precision as input, and 
> constructs a rect with ints as input:
>
> agg::rect_i rect((int)l, height - (int)t, (int)r, height - (int)b);
>
> A rendering buffer is created with a width based on that rect. Half of the 
> time, the width of that buffer disagrees with the width reported by the 
> original bbox. For example, I can kludge the bbox width so it agrees with the 
> output of copy_from_bbox:
>
> l, b, w, h = bbox.bounds
> r = int(l+w)
> w_mod = r-int(l)
>
> I can use w_mod instead of w as a workaround for the blitting issue I 
> reported, but I wonder if there might be a better solution?
> ------
>
> 
>> Darren Dale wrote:
>> 
>>> On Friday 07 March 2008 4:58:03 pm Darren Dale wrote:
>>> 
>>>> I am having some trouble with the Cursor widget with the qt4agg backend.
>>>> Here is a short script which works with the gtkagg backend with useblit
>>>> either true or false:
>>>>
>>>> ----------
>>>> from matplotlib import rcParams
>>>> rcParams['backend']='gtkagg'
>>>> from pylab import *
>>>> from matplotlib.widgets import Cursor
>>>>
>>>> t = arange(0.0, 1.0, 0.01)
>>>> s = sin(2*2*pi*t)
>>>> ax = subplot(111)
>>>>
>>>> cursor = Cursor(ax, useblit=True)
>>>>
>>>> ax.plot(t, s, 'o')
>>>> axis([0,1,-1,1])
>>>> show()
>>>> ------------
>>>>
>>>> If I use the qt4agg backend, with useblit False, the cursor lines do not
>>>> render. If useblit is True, the lines render but the pixmap inside the
>>>> axes is sheared. I've been looking at the backend_qt4agg code, the
>>>> widgets.Cursor code, and the working animation_blit_qt4 example, but I'm
>>>> stuck. Does anyone have any ideas?
>>>> 
>>> Here is an additional wrinkle, sometimes the pixmap is sheared, and
>>> sometimes it is not. The behavior seems to shift back and forth when I
>>> change the horizontal size of the figure window, bu I don't see a pattern
>>> emerging that would explain why: 556-559 pixels wide is sheared, 560-564
>>> looks ok, 565-567 is sheared, 568 is normal, 569 and 570 are sheared,
>>> etc. The
>>> animation_blit_qt4 demo also has the same problem, depending on the
>>> horizontal size. So confusing.
>>> 
-- 
Michael Droettboom
Science Software Branch
Operations and Engineering Division
Space Telescope Science Institute
Operated by AURA for NASA
From: Darren D. <dar...@co...> - 2008年03月10日 12:52:33
That sounds fine to me. I just wanted to make sure that I wasn't glossing over 
a bug that could turn up elsewhere.
Thanks,
Darren
On Monday 10 March 2008 08:46:36 am Michael Droettboom wrote:
> No, I didn't see this message, but I think we arrived at the same
> conclusion. I think the solution is just to calculate the width and
> height in the same way in both places (copy_to_bbox and the Qt blitting
> code in Python). We can't change bbox.bounds, since many other parts of
> the code rely on that calculation being in pure floating point. But
> there's only two places (in Qt and Qt4) that rely on the rounding
> behavior of copy_to_bbox, and IMHO, the way it does the rounding is the
> sanest way given that the edges must be integer-aligned.
>
> I've committed these changes in r4995.
>
> Cheers,
> Mike
>
> Darren Dale wrote:
> > Hi Mike,
> >
> > On Monday 10 March 2008 08:24:27 am you wrote:
> >> Sorry, I didn't see this latest e-mail before I replied before. I see
> >> the shearing now that I've adjusted window size. Maybe it could be
> >> related to the fact that width != span? Anyway, I'll investigated
> >> further and get back.
> >
> > Thanks for having a look. But before you dig to deep, did you see my last
> > post to this thread?:
> >
> > -----
> > I think this problem is due to a loss of precision in _backend_agg's
> > copy_from_bbox. That method takes a bbox with double precision as input,
> > and constructs a rect with ints as input:
> >
> > agg::rect_i rect((int)l, height - (int)t, (int)r, height - (int)b);
> >
> > A rendering buffer is created with a width based on that rect. Half of
> > the time, the width of that buffer disagrees with the width reported by
> > the original bbox. For example, I can kludge the bbox width so it agrees
> > with the output of copy_from_bbox:
> >
> > l, b, w, h = bbox.bounds
> > r = int(l+w)
> > w_mod = r-int(l)
> >
> > I can use w_mod instead of w as a workaround for the blitting issue I
> > reported, but I wonder if there might be a better solution?
> > ------
> >
> >> Darren Dale wrote:
> >>> On Friday 07 March 2008 4:58:03 pm Darren Dale wrote:
> >>>> I am having some trouble with the Cursor widget with the qt4agg
> >>>> backend. Here is a short script which works with the gtkagg backend
> >>>> with useblit either true or false:
> >>>>
> >>>> ----------
> >>>> from matplotlib import rcParams
> >>>> rcParams['backend']='gtkagg'
> >>>> from pylab import *
> >>>> from matplotlib.widgets import Cursor
> >>>>
> >>>> t = arange(0.0, 1.0, 0.01)
> >>>> s = sin(2*2*pi*t)
> >>>> ax = subplot(111)
> >>>>
> >>>> cursor = Cursor(ax, useblit=True)
> >>>>
> >>>> ax.plot(t, s, 'o')
> >>>> axis([0,1,-1,1])
> >>>> show()
> >>>> ------------
> >>>>
> >>>> If I use the qt4agg backend, with useblit False, the cursor lines do
> >>>> not render. If useblit is True, the lines render but the pixmap inside
> >>>> the axes is sheared. I've been looking at the backend_qt4agg code, the
> >>>> widgets.Cursor code, and the working animation_blit_qt4 example, but
> >>>> I'm stuck. Does anyone have any ideas?
> >>>
> >>> Here is an additional wrinkle, sometimes the pixmap is sheared, and
> >>> sometimes it is not. The behavior seems to shift back and forth when I
> >>> change the horizontal size of the figure window, bu I don't see a
> >>> pattern emerging that would explain why: 556-559 pixels wide is
> >>> sheared, 560-564 looks ok, 565-567 is sheared, 568 is normal, 569 and
> >>> 570 are sheared, etc. The
> >>> animation_blit_qt4 demo also has the same problem, depending on the
> >>> horizontal size. So confusing.
-- 
Darren S. Dale, Ph.D.
Staff Scientist
Cornell High Energy Synchrotron Source
Cornell University
275 Wilson Lab
Rt. 366 & Pine Tree Road
Ithaca, NY 14853
dar...@co...
office: (607) 255-3819
fax: (607) 255-9001
http://www.chess.cornell.edu
From: Ted D. <ted...@jp...> - 2008年03月13日 21:03:00
I'm working on improving the plotting speed of one of our applications. As
part of that, I was looking at how quickly the QtAgg backend is drawing. I
added some print out's to the backend and noticed that it seems to be
drawing everything twice. In the code:
backend_qtagg.py: FigureCanvasQTAgg class:
 def draw( self ):
 """
 Draw the figure when xwindows is ready for the update
 """
 if DEBUG: print "FigureCanvasQtAgg.draw", self
 self.replot = True
 FigureCanvasAgg.draw(self)
 self.repaint( False )
FigureCanvasAgg.draw() will cause a draw the repaint call will cause a draw.
If I comment out the FCAgg.draw() call, my application (QtAgg embedded in a
PyQt program) works fine. I've also run several of the various example
scripts and they seem to work fine as well. Panning, zooming, redraws,
resize, and file saving seem to be unaffected.
Does anyone know why the extra draw call might be necessary?
Ted
From: Darren D. <dar...@co...> - 2008年03月14日 12:23:56
On Thursday 13 March 2008 05:02:36 pm Ted Drain wrote:
> I'm working on improving the plotting speed of one of our applications. As
> part of that, I was looking at how quickly the QtAgg backend is drawing. I
> added some print out's to the backend and noticed that it seems to be
> drawing everything twice. In the code:
>
> backend_qtagg.py: FigureCanvasQTAgg class:
>
> def draw( self ):
> """
> Draw the figure when xwindows is ready for the update
> """
>
> if DEBUG: print "FigureCanvasQtAgg.draw", self
> self.replot = True
> FigureCanvasAgg.draw(self)
> self.repaint( False )
>
>
>
> FigureCanvasAgg.draw() will cause a draw the repaint call will cause a
> draw. If I comment out the FCAgg.draw() call, my application (QtAgg
> embedded in a PyQt program) works fine. I've also run several of the
> various example scripts and they seem to work fine as well. Panning,
> zooming, redraws, resize, and file saving seem to be unaffected.
>
> Does anyone know why the extra draw call might be necessary?
Thank you for pointing this out, Ted. It actually solves a problem I was 
seeing with the qt4agg backend, where the widgets.Cursor crosshairs were not 
being drawn when blitting was disabled.
I removed the lines from qtagg and qt4agg, and saw no problems in the examples 
or my own application, so I checked in the changes - svn 5002.
Darren
From: Michael D. <md...@st...> - 2008年03月24日 12:10:06
Ted Drain wrote:
> I've been investigating performance problems we've been having w/ the Qt
> backends. One problems is that zooming takes forever. I've put a lot of
> timing loops into the backends to see where things are happening and found a
> couple of interesting items. 
>
> The first is that agg seems to get much slower as you zoom in. The agg draw
> time goes up as the zoom level goes up. These are plots that are completely
> done w/ the Ellipse patch. Using the Arc patch helps but is about 10%
> slower when not zooming. 
> 
Out of curiosity -- are you using matplotlib 0.91.2, or the SVN trunk? 
The SVN trunk has about 25% faster out-of-bounds vertex removal that 
should improve this.
> The second (and reason for the email), is that the QtAgg backends are
> redrawing the whole plot twice when zooming w/ the mouse. 
It looks like Darren has addressed this part...
Cheers,
Mike
-- 
Michael Droettboom
Science Software Branch
Operations and Engineering Division
Space Telescope Science Institute
Operated by AURA for NASA
From: Darren D. <dar...@co...> - 2008年03月24日 13:00:37
On Monday 24 March 2008 08:09:56 am Michael Droettboom wrote:
> Ted Drain wrote:
> > I've been investigating performance problems we've been having w/ the Qt
> > backends. One problems is that zooming takes forever. I've put a lot of
> > timing loops into the backends to see where things are happening and
> > found a couple of interesting items.
> >
> > The first is that agg seems to get much slower as you zoom in. The agg
> > draw time goes up as the zoom level goes up. These are plots that are
> > completely done w/ the Ellipse patch. Using the Arc patch helps but is
> > about 10% slower when not zooming.
>
> Out of curiosity -- are you using matplotlib 0.91.2, or the SVN trunk?
> The SVN trunk has about 25% faster out-of-bounds vertex removal that
> should improve this.
>
> > The second (and reason for the email), is that the QtAgg backends are
> > redrawing the whole plot twice when zooming w/ the mouse.
>
> It looks like Darren has addressed this part...
That was a different redundant draw() call that Ted reported earlier. I just 
committed this fix, thanks Ted.
Darren
Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.
Thanks for helping keep SourceForge clean.
X





Briefly describe the problem (required):
Upload screenshot of ad (required):
Select a file, or drag & drop file here.
Screenshot instructions:

Click URL instructions:
Right-click on the ad, choose "Copy Link", then paste here →
(This may not be possible with some types of ads)

More information about our ad policies

Ad destination/click URL:

AltStyle によって変換されたページ (->オリジナル) /