2010-08-19 10 views
16

मैंने एक प्रोग्राम लिखा है जो '.dat' फ़ाइल में डेटा की एक सूची लिखता है, इसके बाद gnuplot का उपयोग करके इसे अलग से प्लॉट करने के इरादे से। क्या मेरे कोड को स्वचालित रूप से साजिश बनाने का कोई तरीका है? जब मैं कोड ग्राफ भी एक एक्स-लेबल, वाई-लेबल और शीर्षक (जो मेरी सी कोड से बदला जा सकता है) के साथ मुद्रित किया जाएगा चलाने के लिए,सी कोड प्लॉट को स्वचालित रूप से ग्राफ़ बनाना

x-coord analytic approximation 
x-coord analytic approximation 
x-coord analytic approximation 
x-coord analytic approximation 
x-coord analytic approximation 
.... 

आदर्श रूप में: मेरी उत्पादन फार्म की है। बहुत धन्यवाद।

+1

हो सकता है कि 'system' समारोह की जाँच करें। – sje397

उत्तर

32

मैं gnuplot के बारे में कुछ और खोजते समय इस पर आया। भले ही यह एक पुराना सवाल है, मैंने सोचा कि मैं कुछ नमूना कोड का योगदान दूंगा। मैं इसे अपने कार्यक्रम के लिए उपयोग करता हूं, और मुझे लगता है कि यह एक सुंदर साफ नौकरी करता है। AFAIK, यह PIPEing केवल यूनिक्स सिस्टम पर काम करता है (विंडोज उपयोगकर्ताओं के लिए नीचे संपादित देखें)। मेरा gnuplot स्थापना उबंटू भंडार से डिफ़ॉल्ट स्थापना है।

#include <stdlib.h> 
#include <stdio.h> 
#define NUM_POINTS 5 
#define NUM_COMMANDS 2 

int main() 
{ 
    char * commandsForGnuplot[] = {"set title \"TITLEEEEE\"", "plot 'data.temp'"}; 
    double xvals[NUM_POINTS] = {1.0, 2.0, 3.0, 4.0, 5.0}; 
    double yvals[NUM_POINTS] = {5.0 ,3.0, 1.0, 3.0, 5.0}; 
    FILE * temp = fopen("data.temp", "w"); 
    /*Opens an interface that one can use to send commands as if they were typing into the 
    *  gnuplot command line. "The -persistent" keeps the plot open even after your 
    *  C program terminates. 
    */ 
    FILE * gnuplotPipe = popen ("gnuplot -persistent", "w"); 
    int i; 
    for (i=0; i < NUM_POINTS; i++) 
    { 
    fprintf(temp, "%lf %lf \n", xvals[i], yvals[i]); //Write the data to a temporary file 
    } 

    for (i=0; i < NUM_COMMANDS; i++) 
    { 
    fprintf(gnuplotPipe, "%s \n", commandsForGnuplot[i]); //Send commands to gnuplot one by one. 
    } 
    return 0; 
} 

संपादित

अपने आवेदन में, मैं भी समस्या यह है कि साजिश जब तक बुला कार्यक्रम बंद कर दिया है प्रकट नहीं होता है में फंस गयी। इसे पाने के लिए, fprintf का उपयोग करने के बाद इसे अपना अंतिम आदेश भेजने के लिए fflush(gnuplotPipe) जोड़ें।

मैंने यह भी देखा है कि विंडोज उपयोगकर्ता popen के स्थान पर उपयोग कर सकते हैं - हालांकि मैं इसकी पुष्टि नहीं कर सकता क्योंकि मेरे पास विंडोज़ स्थापित नहीं है।

संपादित 2

एक plot '-' आदेश वर्ण "e" के बाद डेटा बिंदुओं के बाद gnuplot भेजकर एक फ़ाइल पर लिखने में होने से बचने कर सकते हैं।

उदा।

fprintf(gnuplotPipe, "plot '-' \n"); 
int i; 

for (int i = 0; i < NUM_POINTS; i++) 
{ 
    fprintf(gnuplotPipe, "%lf %lf\n", xvals[i], yvals[i]); 
} 

fprintf(gnuplotPipe, "e"); 
+0

मुझे पता है कि यह उत्तर प्रकाशित होने के बाद से यह वास्तव में लंबा समय रहा है, लेकिन मैंने आपके दूसरे संपादन से कोड का उपयोग किया है और इसके लिए कमांड जोड़ने के लिए 'आदेशों के लिए' कमांडफ्लूपल 'के साथ लूप के लिए कोड का उपयोग किया है , और यह प्लॉट्स है लेकिन यह किसी भी कमांड (शीर्षक, xlabel या ylabel) को नहीं जोड़ता है। अगर मैं ऐसा नहीं करता तो मैं उन्हें कैसे जोड़ सकता हूं? कृपया। –

5

आप या तो एक gnuplot स्क्रिप्ट बना सकते हैं और कमांडलाइन से इस स्क्रिप्ट को प्लॉट करने के लिए gnuplot चलाने वाली प्रक्रिया को स्पैन कर सकते हैं, या आप प्रदत्त इंटरफेस में से किसी एक का उपयोग कर सकते हैं। सी के लिए, वहाँ उपलब्ध निकोलस Devillard से एक POSIX पाइप आधारित इंटरफेस यहाँ है: http://ndevilla.free.fr/gnuplot/ ... और एक iostream आधारित सी ++ संस्करण है Git के माध्यम से उपलब्ध है (देखें: http://www.stahlke.org/dan/gnuplot-iostream/)

सबसे पोर्टेबल और शायद सबसे आसान हालांकि, स्क्रिप्ट प्लॉट करने के लिए अभी भी gnuplot को कॉल करना होगा। जैसा कि sje397 उल्लेख किया गया है, stdlib.h में सिस्टम() कॉल के लिए अपने दस्तावेज़ों की जांच करें।

एक sidenote पर, जीएनयू प्लॉट्यूटिल भी हैं, जो libplot प्रदान करता है, डेटासेट प्लॉट करने के लिए एक लाइब्रेरी, जिसे आप अपने आवेदन में उपयोग कर सकते हैं। देखें: http://www.gnu.org/software/plotutils/

+1

मैं इन सभी दस्तावेज सामग्री को समझने में शानदार नहीं हूं लेकिन मुझे सिस्टम(): इंट सिस्टम (कॉन्स char * कमांड) के लिए घोषणा मिली है; क्या यह सिर्फ कुछ ऐसा जोड़ने का मामला है ?: सिस्टम (gnuplot plot "data_set.dat" पंक्तियों का उपयोग करके 1: 2 के साथ); – JMzance

+1

अंत में मैं इस तरह कुछ के लिए गया: – JMzance

+1

# शामिल "gnuplot_i.h" int मुख्य (शून्य) { फ़ाइल * आउटफाइल; आउटफाइल = फॉपेन ("Flight_Path.dat", "w"); /* इटरेटिव लूप जो आउटपुट फ़ाइल को प्रिंट करता है: example.dat */ fclose (outFile); gnuplot_ctrl * k; के = gnuplot_init(); gnuplot_set_xlabel (के, "एक्स"); gnuplot_set_ylabel (के, "वाई"); gnuplot_cmd (k, input_x); gnuplot_cmd (k, input_y); gnuplot_cmd (k, "शीर्षक शीर्षक \" ड्रैग \ "" के साथ प्रक्षेपवक्र); gnuplot_cmd (कश्मीर, "साजिश \" Flight_Path.dat \ "1 का उपयोग: 2 शीर्षक \" उड़ान पथ \ "लाइनों के साथ, \ नींद (7); gnuplot_close (के); वापसी 0;} – JMzance

2

हालांकि मैं ऐसा करने का तरीके का एक बहुत, ऐसा करने का सबसे आसान तरीका है प्रणाली() (stdlib.h से) का उपयोग करके किया जाएगा सी में समारोह पहले एक gnuplot कर देखा है स्क्रिप्ट और इसे "name.gp" के रूप में सहेजें (न तो नाम और न ही एक्सटेंशन पदार्थ)।
एक साधारण स्क्रिप्ट होगा,

plot 'Output.dat' with lines 

इस स्क्रिप्ट फ़ाइल सहेजने के बाद, बस अपने कोड के अंत में
system("gnuplot -p 'name.gp'");
जोड़ें।
यह उतना आसान है जितना।

0

मैंने एक अस्थायी फ़ाइल के उपयोग से परहेज करते हुए एक फ्लोट सरणी प्लॉट करने के स्वीकृत उत्तर को अनुकूलित किया है। इसमें, float* data_ सरणी और size_t size_ इसका आकार है। उम्मीद है कि यह किसी के लिए सहायक है!

चीयर्स,
एन्ड्रेस

void plot(const char* name="FloatSignal"){ 
    // open persistent gnuplot window 
    FILE* gnuplot_pipe = popen ("gnuplot -persistent", "w"); 
    // basic settings 
    fprintf(gnuplot_pipe, "set title '%s'\n", name); 
    // fill it with data 
    fprintf(gnuplot_pipe, "plot '-'\n"); 
    for(size_t i=0; i<size_; ++i){ 
    fprintf(gnuplot_pipe, "%zu %f\n", i, data_[i]); 
    } 
    fprintf(gnuplot_pipe, "e\n"); 
    // refresh can probably be omitted 
    fprintf(gnuplot_pipe, "refresh\n"); 
} 
संबंधित मुद्दे