Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation
 
PerlMonks  

Comment on

( #3333=superdoc: print w/ replies, xml ) Need Help??

For your graphing enjoyment...an L or C Impedance Graph with selectable frequency sweep and scaling.

Original version used the Gnome viewer to display the graph. This "final" version uses a PaintDC and is thus platform independant. Many thanks to Mark Dootson for the PaintDC code.

#! /home/pete/CitrusPerl/perl/bin/perl # ImpedanceGraph2.pl # Impedance calculator for Ls & Cs with graphic display # # Example of using GD::Graph with wxPerl to draw a simple line graph. # # Calculates and graphs the L or C impedance for a range of frequencie +s. # Graph and save_chart borrowed from GD::Graph sample51.pl # # Notes: Original version used the Linux Gnome File Viewer - eog - to +display the graph file. # # This version uses a Display Dialog and Display Panel to display +the # png graph image using a PaintDC. This version is platform Indepe +ndant. # # James M. Lynes, Jr. # Last Modified: June 29, 2013 # # DisplayDialog and DisplayPanel code provided by Mark Dootson, integr +ated June 29, 2013. # package main; use strict; use warnings; my $app = App->new(); $app->MainLoop; package App; use strict; use warnings; use base 'Wx::App'; sub OnInit { Wx::InitAllImageHandlers(); my $frame = Frame->new(); $frame->Show(1); } package DisplayPanel; use strict; use warnings; use Wx qw(:everything); use base qw(Wx::Panel); use Wx::Event qw( EVT_PAINT ); sub new { my ($class, $parent, $bitmap) = @_; my $self = $class->SUPER::new($parent, -1, wxDefaultPosition, [ $bitmap->GetWidth, $bitmap->GetHeight +], wxBORDER_NONE); $self->{bitmap} = $bitmap; EVT_PAINT($self, \&OnEvtPaint); return $self; } sub OnEvtPaint { my ($self, $event) = @_; my $dc = Wx::PaintDC->new($self); $dc->DrawBitmap($self->{bitmap}, 0,0,0); } package DisplayDialog; use strict; use warnings; use Wx qw(:everything); use base qw(Wx::Dialog); sub new { my($class, $parent, $image) = @_; my $self = $class->SUPER::new($parent, -1, 'Impedance vs. Frequenc +y Graph'); my $bitmap = Wx::Bitmap->new($image); my $canvas = DisplayPanel->new($self, $bitmap); my $sizer = Wx::BoxSizer->new(wxVERTICAL); $sizer->Add($canvas,1,wxEXPAND|wxALL,0); $self->SetSizerAndFit($sizer); return $self; } package Frame; use strict; use warnings; use Wx qw(:everything); use base qw(Wx::Frame); use Wx::Event qw(EVT_BUTTON EVT_CHOICE); use GD::Graph::lines; use Data::Dumper; sub new { my($self) = @_; $self = $self->SUPER::new(undef, -1, "L or C Impedance Graph", wxDefaultPosition, [375, 550]); my @Inductors = ("nH", "uH", "mH"); my @Capacitors = ("pF", "nF", "uF"); my @Frequency = ("Hz", "KHz", "MHz"); $self->{lmultiplyer} = 1E-09; # nH Default Scale Factors $self->{cmultiplyer} = 1E-12; # pF $self->{flmultiplyer} = 1E06; # MHz $self->{fhmultiplyer} = 1E06; # MHz $self->{swmultiplyer} = 1E06; # Mhz $self->{xamultiplyer} = 1E06; # Mhz $self->{st1} = Wx::StaticText->new($self, -1, "Inductor Value", Wx +::Point->new(25,50), wxDefaultSize, wxALIGN_LEFT); $self->{st2} = Wx::StaticText->new($self, -1, "Capacitor Value", W +x::Point->new(25,100), wxDefaultSize, wxALIGN_LEFT); $self->{st3} = Wx::StaticText->new($self, -1, "Sweep Start", Wx::P +oint->new(25,150), wxDefaultSize, wxALIGN_LEFT); $self->{st4} = Wx::StaticText->new($self, -1, "Sweep End", Wx::Poi +nt->new(25,200), wxDefaultSize, wxALIGN_LEFT); $self->{st5} = Wx::StaticText->new($self, -1, "Sweep Step", Wx::Po +int->new(25,250), wxDefaultSize, wxALIGN_LEFT); $self->{st6} = Wx::StaticText->new($self, -1, "Enter an L or C and + a Sweep Range to be Graphed", Wx::Point->new(25,15), wxDefaul +tSize, wxALIGN_LEFT); $self->{st7} = Wx::StaticText->new($self, -1, "Y-Axis Max", Wx::Po +int->new(25,450), wxDefaultSize, wxALIGN_LEFT); $self->{st8} = Wx::StaticText->new($self, -1, "Y-Axis Ticks", Wx:: +Point->new(25,475), wxDefaultSize, wxALIGN_LEFT); $self->{st8} = Wx::StaticText->new($self, -1, "X-Axis Scale", Wx:: +Point->new(25,500), wxDefaultSize, wxALIGN_LEFT); $self->{tc1} = Wx::TextCtrl->new($self, -1, "", Wx::Point->new(150 +,50), Wx::Size->new(100,20)); $self->{tc2} = Wx::TextCtrl->new($self, -1, "", Wx::Point->new(150 +,100), Wx::Size->new(100,20)); $self->{tc3} = Wx::TextCtrl->new($self, -1, "", Wx::Point->new(150 +,150), Wx::Size->new(100,20)); $self->{tc4} = Wx::TextCtrl->new($self, -1, "", Wx::Point->new(150 +,200), Wx::Size->new(100,20)); $self->{tc5} = Wx::TextCtrl->new($self, -1, "", Wx::Point->new(150 +,250), Wx::Size->new(100,20)); $self->{tc6} = Wx::TextCtrl->new($self, -1, "", Wx::Point->new(150 +,450), Wx::Size->new(100,20)); $self->{tc7} = Wx::TextCtrl->new($self, -1, "", Wx::Point->new(150 +,475), Wx::Size->new(100,20)); $self->{tc1}->SetValue(0); # L = 0 Default Data Values $self->{tc2}->SetValue(0); # C = 0 $self->{tc3}->SetValue(1); # 1 MHz $self->{tc4}->SetValue(30); # 30 MHz $self->{tc5}->SetValue(1); # 1 MHz $self->{tc6}->SetValue(10000); # 10K ohms $self->{tc7}->SetValue(20); # 20 ticks $self->{lc} = Wx::Choice->new($self, 1, Wx::Point->new(250, 50), w +xDefaultSize, \@Inductors); $self->{cc} = Wx::Choice->new($self, 2, Wx::Point->new(250, 100), +wxDefaultSize, \@Capacitors); $self->{flc} = Wx::Choice->new($self, 3, Wx::Point->new(250, 150), + wxDefaultSize, \@Frequency); $self->{fhc} = Wx::Choice->new($self, 4, Wx::Point->new(250, 200), + wxDefaultSize, \@Frequency); $self->{swc} = Wx::Choice->new($self, 5, Wx::Point->new(250, 250), + wxDefaultSize, \@Frequency); $self->{xscale} = Wx::Choice->new($self, 6, Wx::Point->new(150, 50 +0), wxDefaultSize, \@Frequency); $self->{flc}->SetSelection(2); # MHz Defaut Choices $self->{fhc}->SetSelection(2); # MHz $self->{swc}->SetSelection(2); # MHz $self->{xscale}->SetSelection(2); # MHz $self->{bt1} = Wx::Button->new($self, 4, "Graph Cs", Wx::Point->ne +w(25,350), wxDefaultSize); $self->{bt1} = Wx::Button->new($self, 5, "Graph Ls", Wx::Point->ne +w(150,350), wxDefaultSize); $self->{bt1} = Wx::Button->new($self, 6, "Clear C and L", Wx::Poin +t->new(25,300), wxDefaultSize); $self->{bt2} = Wx::Button->new($self, wxID_CLOSE, "Exit", Wx::Poin +t->new(25,400), wxDefaultSize); EVT_BUTTON($self, 4, \&CalcC); EVT_BUTTON($self, 5, \&CalcL); EVT_BUTTON($self, 6, \&ClearAll); EVT_BUTTON($self, wxID_CLOSE, \&Close); EVT_CHOICE($self, 1, \&ChoiceL); EVT_CHOICE($self, 2, \&ChoiceC); EVT_CHOICE($self, 3, \&ChoiceFL); EVT_CHOICE($self, 4, \&ChoiceFH); EVT_CHOICE($self, 5, \&ChoiceSW); EVT_CHOICE($self, 6, \&ChoiceXA); return $self; } sub CalcC { my($self, $event) = @_; my @xvalues; my @yvalues; my $C = $self->{tc2}->GetValue * $self->{cmultiplyer}; if($C == 0) {return}; my $fl = $self->{tc3}->GetValue * $self->{flmultiplyer}; my $fh = $self->{tc4}->GetValue * $self->{fhmultiplyer}; my $sw = $self->{tc5}->GetValue * $self->{swmultiplyer}; for(my $F = $fl; $F <= $fh; $F += $sw) { my $I = 1/(6.28 * $C * $F); push(@xvalues, $F/$self->{xamultiplyer}); push(@yvalues, $I); } Graph($self, \@xvalues, \@yvalues); } sub CalcL { my($self, $event) = @_; my @xvalues; my @yvalues; my $L = $self->{tc1}->GetValue * $self->{lmultiplyer}; if($L == 0) {return}; my $fl = $self->{tc3}->GetValue * $self->{flmultiplyer}; my $fh = $self->{tc4}->GetValue * $self->{fhmultiplyer}; my $sw = $self->{tc5}->GetValue * $self->{swmultiplyer}; for(my $F = $fl; $F <= $fh; $F += $sw) { my $I = 6.28 * $L * $F; push(@xvalues, $F/$self->{xamultiplyer}); push(@yvalues, $I); } Graph($self, \@xvalues, \@yvalues); } sub ChoiceL { my($self, $event) = @_; if($self->{lc}->GetSelection == 0) {$self->{lmultiplyer} = 1E-09}; + # nH if($self->{lc}->GetSelection == 1) {$self->{lmultiplyer} = 1E-06}; + # uH if($self->{lc}->GetSelection == 2) {$self->{lmultiplyer} = 1E-03}; + # mH } sub ChoiceC { my($self, $event) = @_; if($self->{cc}->GetSelection == 0) {$self->{cmultiplyer} = 1E-12}; + # pF if($self->{cc}->GetSelection == 1) {$self->{cmultiplyer} = 1E-09}; + # nF if($self->{cc}->GetSelection == 2) {$self->{cmultiplyer} = 1E-06}; + # uF } sub ChoiceFL { my($self, $event) = @_; if($self->{flc}->GetSelection == 0) {$self->{flmultiplyer} = 1}; + # Hz if($self->{flc}->GetSelection == 1) {$self->{flmultiplyer} = 1E03} +; # KHz if($self->{flc}->GetSelection == 2) {$self->{flmultiplyer} = 1E06} +; # MHz } sub ChoiceFH { my($self, $event) = @_; if($self->{fhc}->GetSelection == 0) {$self->{fhmultiplyer} = 1}; + # Hz if($self->{fhc}->GetSelection == 1) {$self->{fhmultiplyer} = 1E03} +; # KHz if($self->{fhc}->GetSelection == 2) {$self->{fhmultiplyer} = 1E06} +; # MHz } sub ChoiceSW { my($self, $event) = @_; if($self->{swc}->GetSelection == 0) {$self->{swmultiplyer} = 1}; + # Hz if($self->{swc}->GetSelection == 1) {$self->{swmultiplyer} = 1E03} +; # KHz if($self->{swc}->GetSelection == 2) {$self->{swmultiplyer} = 1E06} +; # MHz } sub ChoiceXA { my($self, $event) = @_; if($self->{xscale}->GetSelection == 0) {$self->{xamultiplyer} = 1} +; # Hz if($self->{xscale}->GetSelection == 1) {$self->{xamultiplyer} = 1E +03}; # KHz if($self->{xscale}->GetSelection == 2) {$self->{xamultiplyer} = 1E +06}; # MHz } sub ClearAll { my($self, $event) = @_; $self->{tc1}->SetValue(0); # L = 0 $self->{tc2}->SetValue(0); # C = 0 } sub Close { my($self, $event) = @_; $self->Destroy; } sub Graph { # GD::Graph::lines Line Graph Module my($self, $xvalues, $yvalues) = @_; # From GDGraph-1.45.tar +.gz sample51.pl my @data = ( # Other graph formats are supported. +See the pod. [(@{$xvalues}) ], [(@{$yvalues})], ); my $xlskip = (int(@{$xvalues}) / 30) + 1; # Only about 30 label +s will fit on the x axis. Gotta skip some. # Labels still overwrite on occasions. Play wi +th the scaling. my $my_graph = new GD::Graph::lines(600,400); my $xscale = $self->{xscale}->GetStringSelection; # Hz, KHz, MH +z $my_graph->set( x_label => "Frequency($xscale)", y_label => 'Impedance(Ohms)', title => 'Impedance vs. Frequency', y_max_value => $self->{tc6}->GetValue, y_min_value => 0, y_tick_number => $self->{tc7}->GetValue, y_label_skip => 2, box_axis => 0, line_width => 3, transparent => 0, x_label_position => 1/2, x_label_skip => $xlskip, ); my $gd = $my_graph->plot(\@data); #save_chart($my_graph, 'impedance'); # From sample51.pl not + used in this configuration #system('eog /home/pete/Projects/perlprojects/RFdesign/impedance.g +if'); # Get the raw PNG data my $png = $gd->png; # Get a file handle and load it as a wxImage open my $fh, '<', \$png; my $img = Wx::Image->new($fh, &Wx::wxBITMAP_TYPE_PNG); close $fh; my $dialog = DisplayDialog->new($self, $img); $dialog->Centre; $dialog->ShowModal(); $dialog->Destroy; } sub save_chart # Separate sub because the sampl +e51.pl was setup this way. { # Not used in this configuration my $chart = shift or die "Need a chart!"; my $name = shift or die "Need a name!"; local(*OUT); my $ext = $chart->export_format; open(OUT, ">$name.$ext") or die "Cannot open $name.$ext for write: $!"; binmode OUT; print OUT $chart->gd->$ext(); close OUT; } 1;

Cross-Posted to wxperl-users.org

James

There's never enough time to do it right, but always enough time to do it over...


In reply to wxPerl Integration with GD::Graph Example by jmlynesjr

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post; it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.
  • Log In?
    Username:
    Password:

    What's my password?
    Create A New User
    Chatterbox?
    and the web crawler heard nothing...

    How do I use this? | Other CB clients
    Other Users?
    Others perusing the Monastery: (12)
    As of 2015-07-31 14:10 GMT
    Sections?
    Information?
    Find Nodes?
    Leftovers?
      Voting Booth?

      The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









      Results (278 votes), past polls